diff --git a/.github/workflows/bindgen.yml b/.github/workflows/bindgen.yml index 87b2cdb1d8..bd1489911e 100644 --- a/.github/workflows/bindgen.yml +++ b/.github/workflows/bindgen.yml @@ -3,203 +3,173 @@ name: bindgen on: push: branches: - - master + - main pull_request: branches: - - master + - main + merge_group: + branches: + - main jobs: rustfmt: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Install stable - uses: actions-rs/toolchain@v1 + - name: Install nightly + uses: dtolnay/rust-toolchain@master with: - profile: minimal - # TODO: Should ideally be stable, but we use some nightly-only - # features. toolchain: nightly - override: true - components: rustfmt, clippy + components: rustfmt - name: Run rustfmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: -- --check + run: cargo +nightly fmt -- --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - name: Run clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- --cfg test + run: cargo clippy --all-targets --workspace --exclude bindgen-integration --exclude tests_expectations -- -D warnings msrv: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - 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 - uses: actions-rs/toolchain@v1 + - name: Install msrv for lib + uses: dtolnay/rust-toolchain@master with: - profile: minimal - # MSRV below is documented in README.md, please update that if you - # change this. - toolchain: 1.54.0 - override: true + toolchain: ${{ steps.metadata.outputs.rust-version }} - - name: Build with msrv - run: rm Cargo.lock && cargo +1.54.0 build --lib + - name: Test lib with msrv + run: cargo +${{ steps.metadata.outputs.rust-version }} test --package bindgen - quickchecking: + - name: Install msrv for cli + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ steps.metadata.outputs.rust-version }} + + - name: Test cli with msrv + run: cargo +${{ steps.metadata.outputs.rust-version }} build --package bindgen-cli + + minimal: runs-on: ubuntu-latest + env: + RUSTFLAGS: -D warnings steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Install stable - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - name: Check without default features + run: cargo check -p bindgen --no-default-features --features=runtime + + docs: + runs-on: ubuntu-latest + env: + RUSTDOCFLAGS: -D warnings + steps: + - uses: actions/checkout@v4 + + - name: Generate documentation for `bindgen` + run: cargo doc --document-private-items --no-deps -p bindgen + + - name: Generate documentation for `bindgen-cli` + run: cargo doc --document-private-items --no-deps -p bindgen-cli + + quickchecking: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 # TODO: Actually run quickchecks once `bindgen` is reliable enough. - name: Build quickcheck tests - run: cd tests/quickchecking && cargo test + run: cd bindgen-tests/tests/quickchecking && cargo test test-expectations: runs-on: ${{matrix.os}} strategy: matrix: - # TODO(#1954): These should be run on mac too, but turns out they're - # broken. - os: [ubuntu-latest] + os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest] steps: - - uses: actions/checkout@v2 - - - name: Install stable - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: actions/checkout@v4 - name: Test expectations - run: cd tests/expectations && cargo test + 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 - llvm_version: ["4.0", "5.0", "9.0"] - main_tests: [1] + 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"] release_build: [0, 1] no_default_features: [0, 1] # FIXME: There are no pre-built static libclang libraries, so the # `static` feature is not testable atm. feature_runtime: [0, 1] feature_extra_asserts: [0] - feature_testing_only_docs: [0] - - exclude: - # 4.0 is too old to support regular dynamic linking, so this - # is not expected to work. - - os: ubuntu-latest - llvm_version: "4.0" - no_default_features: 1 - feature_runtime: 0 include: # Test with extra asserts + docs just with latest llvm versions to # prevent explosion - - os: ubuntu-latest - llvm_version: "9.0" + - 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 - feature_testing_only_docs: 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: "9.0" - # main_tests: 0 - # release_build: 0 - # feature_extra_asserts: 0 - # feature_testing_only_docs: 0 # Ensure stuff works on macos too - - os: macos-latest - llvm_version: "9.0" + - platform: + os: macos-latest + llvm_version: "16.0" release_build: 0 no_default_features: 0 feature_extra_asserts: 0 - feature_testing_only_docs: 0 steps: - - uses: actions/checkout@v2 - - - 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}} + - uses: actions/checkout@v4 - name: Install stable - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: stable - target: ${{matrix.target.rust}} - override: true - + - name: Install libtinfo + if: startsWith(matrix.platform.os, 'ubuntu') + run: | + 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_FEATURE_TESTING_ONLY_DOCS: ${{matrix.feature_testing_only_docs}} 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 test-book: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - name: Install stable - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: actions/checkout@v4 # NOTE(emilio): Change deploy-book as well if you change this. - name: Test book @@ -207,3 +177,33 @@ jobs: 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 ./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, 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. + if: always() # make sure this is never "skipped" + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: check if any dependency failed + run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 0000000000..56a264f7f7 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,68 @@ +name: Bump version for release + +on: + workflow_dispatch: + inputs: + level: + description: | + Select the level of the release + required: true + type: choice + options: + - minor + - patch + +jobs: + bump-version: + permissions: + id-token: write + pull-requests: write + contents: write + + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure gitsign + uses: chainguard-dev/actions/setup-gitsign@main + + - name: Install cargo-release + uses: taiki-e/install-action@v1 + with: + tool: cargo-release + + - name: Install sd + uses: taiki-e/install-action@v1 + with: + tool: sd + + - name: Install npm + uses: actions/setup-node@v4 + + - name: Install doctoc + run: npm install doctoc + + - name: Bump version + run: | + cargo release version ${{ inputs.level }} --execute --no-confirm + + - name: Extract version + run: | + echo "version=$(cargo pkgid -p bindgen | cut -d '#' -f 2)" >> $GITHUB_ENV + + - name: Update changelog + run: | + sd "# Unreleased" "# Unreleased\n## Added\n## Changed\n## Removed\n## Fixed\n## Security\n\n# ${{ env.version }} ($(date -I))" CHANGELOG.md + ./node_modules/doctoc/doctoc.js CHANGELOG.md + + - name: Create PR + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: bump-version/${{ env.version }} + base: main + commit-message: "Bump crates version to ${{ env.version }}" + title: "Bump crates version to ${{ env.version }}" + body: | + This pull request was created automatically by GitHub Actions. diff --git a/.github/workflows/create-tag.yml b/.github/workflows/create-tag.yml new file mode 100644 index 0000000000..f636991c38 --- /dev/null +++ b/.github/workflows/create-tag.yml @@ -0,0 +1,49 @@ +name: Create tag for release + +on: + pull_request: + types: + - closed + workflow_dispatch: + inputs: + commit: + description: 'Commit hash' + required: true + type: string +jobs: + create-tag: + 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 + + - name: Extract version + run: | + echo "version=$(cargo pkgid -p bindgen | cut -d '#' -f 2)" >> $GITHUB_ENV + + - name: Create tag + 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 bf03d34b63..7b8cacc55d 100644 --- a/.github/workflows/deploy-book.yml +++ b/.github/workflows/deploy-book.yml @@ -3,26 +3,19 @@ name: Deploy book on: push: branches: - - master + - main jobs: deploy-book: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: persist-credentials: false - - name: Install stable - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - 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 new file mode 100644 index 0000000000..d8602f9ad9 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,27 @@ +# This is triggered after the Release workflow successfully completes its run +name: Publish on crates.io +on: + workflow_run: + workflows: + - Release + types: + - completed +env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} +jobs: + cargo-publish: + runs-on: ubuntu-latest + 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 }}" + - name: Checkout sources + uses: actions/checkout@v4 + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + - name: Publish bindgen (lib) + run: cargo publish --package bindgen --token ${CARGO_REGISTRY_TOKEN} + - name: Publish bindgen-cli + run: cargo publish --package bindgen-cli --token ${CARGO_REGISTRY_TOKEN} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..6620b80c98 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,291 @@ +# 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 dist (archives, installers, hashes) +# * uploads those artifacts to temporary workflow zip +# * on success, uploads the artifacts to a GitHub Release +# +# Note that the GitHub Release will be created with a generated +# title/body based on your changelogs. + +name: Release +permissions: + "contents": "write" + +# This task will run whenever you push a git tag that looks like a version +# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. +# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where +# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION +# 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 dist-able). +# +# If PACKAGE_NAME isn't specified, then the announcement will be for all +# (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). +# +# If you push multiple tags at once, separate instances of this workflow will +# spin up, creating an independent announcement for each one. However, GitHub +# will hard limit this to 3 tags per commit, as it will assume more tags is a +# mistake. +# +# If there's a prerelease-style suffix to the version, then the release(s) +# will be marked as a prerelease. +on: + pull_request: + push: + tags: + - '**[0-9]+.[0-9]+.[0-9]+*' + +jobs: + # Run 'dist plan' (or host) to determine what tasks we need to do + plan: + runs-on: "ubuntu-22.04" + outputs: + val: ${{ steps.plan.outputs.manifest }} + tag: ${{ !github.event.pull_request && github.ref_name || '' }} + tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + publishing: ${{ !github.event.pull_request }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - 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.28.0/cargo-dist-installer.sh | sh" + - name: Cache dist + uses: actions/upload-artifact@v4 + with: + name: cargo-dist-cache + 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. + # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* + # but also really annoying to build CI around when it needs secrets to work right.) + - id: plan + run: | + 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" + uses: actions/upload-artifact@v4 + with: + name: artifacts-plan-dist-manifest + path: plan-dist-manifest.json + + # Build and packages all the platform-specific things + build-local-artifacts: + name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) + # Let the initial task tell us to not run (currently very blunt) + needs: + - plan + 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 dist in create-release. + # Each member of the matrix has the following arguments: + # + # - runner: the github 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 + steps: + - name: enable windows longpaths + run: | + git config --global core.longpaths true + - uses: actions/checkout@v4 + with: + submodules: recursive + - 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 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - name: Install dependencies + run: | + ${{ matrix.packages_install }} + - name: Build artifacts + run: | + # Actually do builds and make zips and whatnot + 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 + # to "real" actions without writing to env-vars, and writing to env-vars has + # inconsistent syntax between shell and powershell. + shell: bash + run: | + # Parse out what we just built and upload it to scratch storage + echo "paths<> "$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" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + with: + name: artifacts-build-local-${{ join(matrix.targets, '_') }} + path: | + ${{ steps.cargo-dist.outputs.paths }} + ${{ env.BUILD_MANIFEST_NAME }} + + # Build and package all the platform-agnostic(ish) things + build-global-artifacts: + needs: + - plan + - build-local-artifacts + runs-on: "ubuntu-22.04" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install cached dist + uses: actions/download-artifact@v4 + with: + name: cargo-dist-cache + path: ~/.cargo/bin/ + - 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 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - id: cargo-dist + shell: bash + run: | + 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" + jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + cp dist-manifest.json "$BUILD_MANIFEST_NAME" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + with: + name: artifacts-build-global + path: | + ${{ steps.cargo-dist.outputs.paths }} + ${{ env.BUILD_MANIFEST_NAME }} + # Determines if we should publish/announce + host: + needs: + - plan + - build-local-artifacts + - build-global-artifacts + # Only run if we're "publishing", and only if local and global didn't fail (skipped is fine) + 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-22.04" + outputs: + val: ${{ steps.host.outputs.manifest }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install cached dist + uses: actions/download-artifact@v4 + with: + name: cargo-dist-cache + path: ~/.cargo/bin/ + - run: chmod +x ~/.cargo/bin/dist + # Fetch artifacts from scratch-storage + - name: Fetch artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - id: host + shell: bash + run: | + 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" + - name: "Upload dist-manifest.json" + uses: actions/upload-artifact@v4 + with: + # Overwrite the previous copy + name: artifacts-dist-manifest + path: dist-manifest.json + # Create a GitHub Release while uploading all files to it + - name: "Download GitHub Artifacts" + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: artifacts + merge-multiple: true + - name: Cleanup + run: | + # Remove the granular manifests + rm -f artifacts/*-dist-manifest.json + - name: Create GitHub Release + env: + PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" + ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" + ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" + RELEASE_COMMIT: "${{ github.sha }}" + run: | + # Write and read notes from a file to avoid quoting breaking things + echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + + gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + + announce: + needs: + - plan + - host + # use "always() && ..." to allow us to wait for all publish jobs while + # 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-22.04" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive diff --git a/.gitignore b/.gitignore index f5c3381c81..a610640e5e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ target/ *~ bindgen-integration/Cargo.lock -tests/expectations/Cargo.lock +bindgen-tests/tests/expectations/Cargo.lock +bindgen-tests/tests/quickchecking/Cargo.lock #*# # Test script output @@ -17,3 +18,8 @@ csmith-fuzzing/platform.info # Backups of test cases from C-Reduce **/*.orig + +# node.js files +node_modules +package-lock.json +package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 73c405c7da..74ff973751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,159 +1,713 @@ - - [Unreleased](#unreleased) - [Added](#added) - - [Fixed](#fixed) - [Changed](#changed) - - [Deprecated](#deprecated) - [Removed](#removed) - - [Fixed](#fixed-1) + - [Fixed](#fixed) - [Security](#security) -- [0.59.1](#0591) - - [Fixed](#fixed-2) -- [0.59.0](#0590) +- [0.72.0 (2025-06-08)](#0720-2025-06-08) - [Added](#added-1) - - [Fixed](#fixed-3) - [Changed](#changed-1) -- [0.58.1](#0581) + - [Removed](#removed-1) + - [Fixed](#fixed-1) +- [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) -- [0.58.0](#0580) + - [Changed](#changed-2) + - [Removed](#removed-2) + - [Fixed](#fixed-3) +- [0.70.1 (2024-08-20)](#0701-2024-08-20) - [Added](#added-3) + - [Changed](#changed-3) + - [Removed](#removed-3) - [Fixed](#fixed-4) - - [Changed](#changed-2) - - [Deprecated](#deprecated-1) - - [Removed](#removed-1) - - [Fixed](#fixed-5) - [Security](#security-1) -- [0.57.0](#0570) +- [0.70.0 (2024-08-16)](#0700-2024-08-16) - [Added](#added-4) - - [Fixed](#fixed-6) -- [0.56.0](#0560) + - [Changed](#changed-4) + - [Removed](#removed-4) + - [Fixed](#fixed-5) + - [Security](#security-2) +- [0.69.4 (2024-02-04)](#0694-2024-02-04) - [Added](#added-5) - - [Changed](#changed-3) + - [Changed](#changed-5) + - [Removed](#removed-5) + - [Fixed](#fixed-6) + - [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) -- [0.55.1](#0551) + - [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) -- [0.55.0](#0550) - - [Removed](#removed-2) - - [Added](#added-6) - - [Changed](#changed-4) + - [Security](#security-5) +- [0.69.1 (2023-11-02)](#0691-2023-11-02) - [Fixed](#fixed-9) -- [0.54.1](#0541) - - [Added](#added-7) - - [Changed](#changed-5) - - [Fixed](#fixed-10) -- [0.54.0](#0540) +- [0.69.0 (2023-11-01)](#0690-2023-11-01) - [Added](#added-8) - - [Changed](#changed-6) + - [Changed](#changed-8) + - [Removed](#removed-8) + - [Fixed](#fixed-10) + - [Security](#security-6) +- [0.68.1](#0681) - [Fixed](#fixed-11) -- [0.53.3](#0533) +- [0.68.0](#0680) - [Added](#added-9) + - [Changed](#changed-9) + - [Removed](#removed-9) - [Fixed](#fixed-12) -- [0.53.2](#0532) - - [Changed](#changed-7) -- [0.53.1](#0531) +- [0.67.0](#0670) +- [0.66.1](#0661) + - [Removed](#removed-10) +- [0.66.0](#0660) - [Added](#added-10) -- [0.53.0](#0530) - - [Added](#added-11) - - [Changed](#changed-8) + - [Changed](#changed-10) + - [Removed](#removed-11) +- [0.65.1](#0651) - [Fixed](#fixed-13) -- [0.52.0](#0520) +- [0.65.0](#0650) + - [Added](#added-11) + - [Changed](#changed-11) + - [Removed](#removed-12) +- [0.64.0](#0640) - [Added](#added-12) - - [Changed](#changed-9) + - [Changed](#changed-12) +- [0.63.0](#0630) + - [Added](#added-13) + - [Changed](#changed-13) + - [Removed](#removed-13) +- [0.62.0](#0620) + - [Added](#added-14) + - [Changed](#changed-14) - [Fixed](#fixed-14) -- [0.51.1](#0511) +- [0.61.0](#0610) + - [Added](#added-15) + - [Changed](#changed-15) - [Fixed](#fixed-15) - - [Changed](#changed-10) -- [0.51.0](#0510) +- [0.60.1](#0601) - [Fixed](#fixed-16) - - [Changed](#changed-11) - - [Added](#added-13) +- [0.60.0](#0600) + - [Added](#added-16) + - [Fixed](#fixed-17) + - [Changed](#changed-16) + - [Removed](#removed-14) +- [0.59.2](#0592) +- [0.59.1](#0591) + - [Fixed](#fixed-18) +- [0.59.0](#0590) + - [Added](#added-17) + - [Fixed](#fixed-19) + - [Changed](#changed-17) +- [0.58.1](#0581) + - [Added](#added-18) +- [0.58.0](#0580) + - [Added](#added-19) + - [Fixed](#fixed-20) + - [Changed](#changed-18) + - [Deprecated](#deprecated) + - [Removed](#removed-15) + - [Fixed](#fixed-21) + - [Security](#security-7) +- [0.57.0](#0570) + - [Added](#added-20) + - [Fixed](#fixed-22) +- [0.56.0](#0560) + - [Added](#added-21) + - [Changed](#changed-19) + - [Fixed](#fixed-23) +- [0.55.1](#0551) + - [Fixed](#fixed-24) +- [0.55.0](#0550) + - [Removed](#removed-16) + - [Added](#added-22) + - [Changed](#changed-20) + - [Fixed](#fixed-25) +- [0.54.1](#0541) + - [Added](#added-23) + - [Changed](#changed-21) + - [Fixed](#fixed-26) +- [0.54.0](#0540) + - [Added](#added-24) + - [Changed](#changed-22) + - [Fixed](#fixed-27) +- [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) + - [Fixed](#fixed-29) +- [0.52.0](#0520) + - [Added](#added-28) + - [Changed](#changed-25) + - [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-14) + - [Added](#added-30) - [0.49.3](#0493) - - [Added](#added-15) + - [Added](#added-31) - [0.49.2](#0492) - - [Changed](#changed-12) + - [Changed](#changed-28) - [0.49.1](#0491) - - [Fixed](#fixed-17) - - [Changed](#changed-13) + - [Fixed](#fixed-33) + - [Changed](#changed-29) - [0.49.0](#0490) - - [Added](#added-16) - - [Fixed](#fixed-18) - - [Changed](#changed-14) + - [Added](#added-32) + - [Fixed](#fixed-34) + - [Changed](#changed-30) - [0.48.1](#0481) - - [Fixed](#fixed-19) + - [Fixed](#fixed-35) - [0.48.0](#0480) - - [Changed](#changed-15) - - [Fixed](#fixed-20) + - [Changed](#changed-31) + - [Fixed](#fixed-36) - [0.47.4](#0474) - - [Added](#added-17) + - [Added](#added-33) - [0.47.3](#0473) - - [Changed](#changed-16) + - [Changed](#changed-32) - [0.47.2](#0472) - - [Fixed](#fixed-21) + - [Fixed](#fixed-37) - [0.47.1](#0471) - - [Changed](#changed-17) - - [Fixed](#fixed-22) + - [Changed](#changed-33) + - [Fixed](#fixed-38) - [0.47.0](#0470) - - [Changed](#changed-18) - - [Fixed](#fixed-23) + - [Changed](#changed-34) + - [Fixed](#fixed-39) - [0.33.1 .. 0.46.0](#0331--0460) - - [Added](#added-18) - - [Removed](#removed-3) - - [Changed](#changed-19) - - [Fixed](#fixed-24) + - [Added](#added-34) + - [Removed](#removed-17) + - [Changed](#changed-35) + - [Fixed](#fixed-40) - [0.33.1](#0331) - - [Fixed](#fixed-25) + - [Fixed](#fixed-41) - [0.33.0](#0330) - [0.32.2](#0322) - - [Fixed](#fixed-26) + - [Fixed](#fixed-42) - [0.32.1](#0321) - - [Fixed](#fixed-27) + - [Fixed](#fixed-43) - [0.32.0](#0320) - - [Added](#added-19) - - [Changed](#changed-20) - - [Fixed](#fixed-28) + - [Added](#added-35) + - [Changed](#changed-36) + - [Fixed](#fixed-44) - [0.31.0](#0310) - - [Added](#added-20) - - [Changed](#changed-21) - - [Deprecated](#deprecated-2) - - [Removed](#removed-4) - - [Fixed](#fixed-29) + - [Added](#added-36) + - [Changed](#changed-37) + - [Deprecated](#deprecated-1) + - [Removed](#removed-18) + - [Fixed](#fixed-45) - [0.30.0](#0300) - - [Added](#added-21) - - [Changed](#changed-22) - - [Deprecated](#deprecated-3) - - [Fixed](#fixed-30) + - [Added](#added-37) + - [Changed](#changed-38) + - [Deprecated](#deprecated-2) + - [Fixed](#fixed-46) - [0.29.0](#0290) - - [Added](#added-22) - - [Changed](#changed-23) - - [Fixed](#fixed-31) + - [Added](#added-38) + - [Changed](#changed-39) + - [Fixed](#fixed-47) -------------------------------------------------------------------------------- - # Unreleased +## 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 +## Removed +## Fixed +- Fix regression where the `const` layout tests were triggering the `unnecessary_operation` and `identity_op` clippy warnings. +## Security - * cexpr and nom have been updated, new msrv is 1.46 (#2107). +# 0.70.0 (2024-08-16) +## Added +- Add target mappings for riscv64imac and riscv32imafc. +- Add a complex macro fallback API (#2779). +- 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 field_type_name to FieldInfo. +## Changed +- Remove which and lazy-static dependencies (#2809, #2817). +- Generate compile-time layout tests (#2787). +- Print `bindgen-cli` errors to stderr instead of stdout (#2840) +## Removed +## Fixed +- Fix `--formatter=prettyplease` not working in `bindgen-cli` by adding `prettyplease` feature and + enabling it by default for `bindgen-cli` (#2789) . +- Fix `--allowlist-item` so anonymous enums are no longer ignored (#2827). +- Use clang_getFileLocation instead of clang_getSpellingLocation to fix clang-trunk (#2824). +- Fix generated constants: `f64::INFINITY`, `f64::NEG_ INFINITY`, `f64::NAN` (#2854). +## Security +- Update `tempfile` and `rustix` due to [GHSA-c827-hfw6-qwvm](https://github.com/advisories/GHSA-c827-hfw6-qwvm). -## Deprecated +# 0.69.4 (2024-02-04) +## Added +## Changed +- Allow older itertools. (#2745) +## Removed +## Fixed +## Security + +# 0.69.3 (2024-02-04) +## Added + +- Added blocklist_var (#2731) +- Stabilized thiscall_abi (#2661) + +## Changed + +- Use CR consistently on windows (#2698) +- Replaced peeking_take_while by itertools (#2724) + +## Removed +## Fixed + +- Try to avoid repr(packed) for explicitly aligned types when not needed (#2734) +- Improved destructor handling on Windows (#2663) +- Support Float16 (#2667) +- Fix alignment contribution from bitfields (#2680) +- Fixed msrv build. + +## Security + +- Updated shlex dependency (RUSTSEC-2024-0006) +# 0.69.2 (2024-01-13) +## Added +## Changed ## Removed +## Fixed +- Fixed generation of extern "C" blocks with llvm 18+. See #2689. +## Security + +# 0.69.1 (2023-11-02) ## Fixed +- Allow to run `bindgen -v` without an input header argument. +# 0.69.0 (2023-11-01) + +## Added +- Added the `ParseCallbacks::header_file` callback which runs on every filename passed to `Builder::header`. +- Added the `CargoCallbacks::new` constructor which emits a cargo-rerun line + for every input header file by default. +- Added the `CargoCallbacks::rerun_on_header_files` method to configure whether + a cargo-rerun line should be emitted for every input header file. +## Changed +- The `--wrap-static-fns` feature was updated so function types that has no + argument use `void` as its sole argument. +- `CargoCallbacks` is no longer a [unit-like + struct](https://doc.rust-lang.org/reference/items/structs.html) and the + `CargoCallbacks` constant was added to mitigate the breaking nature of this + change. This constant has been marked as deprecated and users will have to + use the new `CargoCallbacks::new` method in the future. +## Removed +## Fixed +- Allow compiling `bindgen-cli` with a static libclang. +- Emit an opaque integer type for pointer types that don't have the same size + as the target's pointer size. +- Avoid escaping Objective-C method names unless they are `Self`, `self`, + `crate` or `super`. ## Security +# 0.68.1 + +## Fixed +- Fixed errors on the windows artifact build process. + +# 0.68.0 + +## Added +- The `system` ABI is now supported as an option for the `--override-abi` flag. +- The `allowlist_item` method and the `--allowlist-item` flag have been + included to filter items regardless or their kind. +- Include installers as release artifacts on Github. +## Changed +- The `Clone` implementation for `_BindgenUnionField` has been changed to pass + the `incorrect_clone_impl_on_copy_type` Clippy lint. +- The `c_unwind` ABI can be used without a feature gate for any Rust target version + equal to or greater than 1.71. + This comes as a result of the ABI being stabilised (in Rust 1.71). +- Formatting changes when using prettyplease as a formatter due to a new + prettyplease version. +- Avoid generating invalid `CStr` constants when using the `--generate-cstr` + option. +## Removed +- The `extra_assert` and `extra_assert_eq` macros are no longer exported. +## Fixed +- Bindgen no longer panics when parsing an objective-C header that includes a + Rust keyword that cannot be a raw identifier, such as: `self`, `crate`, + `super` or `Self`. + +# 0.67.0 + +This version was skipped due to some problems on the release workflow. + +# 0.66.1 + +## Removed +* Revert source order sorting (#2543) due to correctness regressions #2558. + +# 0.66.0 + +## Added + +* Added the `--generate-cstr` CLI flag to generate string constants as `&CStr` + instead of `&[u8]`. (Requires Rust 1.59 or higher.) +* Added the `--generate-shell-completions` CLI flag to generate completions for + different shells. +* 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. + +## Changed + +* Non-UTF-8 string constants are now generated as references (`&[u8; SIZE]`) + instead of arrays (`[u8; SIZE]`) to match UTF-8 strings. +* Wrappers for static functions that return `void` no longer contain a `return` + statement and only call the static function instead. +* The `--wrap-static-fns` option no longer emits wrappers for static variadic + functions. +* Depfiles generated with `--depfile` or `Builder::depfile` will now properly + generate module names and paths that include spaces by escaping them. To make + the escaping clear and consistent, backslashes are also escaped. +* Updated `bitflags` dependency to 2.2.1. This changes the API of `CodegenConfig`. +* Prettyplease formatting is gated by an optional, enabled by default Cargo + feature when depending on `bindgen` as a library. +* Items are now parsed in the order they appear in source files. This may result in + auto-generated `_bindgen_*` names having a different index. +* Use default visibility for padding fields: Previously, padding fields were + always public. Now, they follow the default visibility for the type they are + in. +* 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. + +## Removed +* Remove redundant Cargo features, which were all implicit: + - bindgen-cli: `env_logger` and `log` removed in favor of `logging` + - bindgen (lib): + + `log` removed in favor of `logging` + + `which` removed in favor of `which-logging` + + `annotate-snippets` removed in favor of `experimental` + +* Prettyplease is available as a `Formatter` variant now. + +# 0.65.1 + +## Fixed + +* The `Builder::rustfmt_bindings` method was added back and tagged as + deprecated instead of being removed. +* Broken documentation links were fixed. + +# 0.65.0 + +## Added + * Added the `Builder::default_visibility` method and the + `--default-visibility` flag to set the default visibility of fields. (#2338) + * Added the `--formatter` CLI flag with the values `none`, `rustfmt` and + `prettyplease` to select which tool will be used to format the bindings. The + default value is `rustfmt`. (#2453) + * Added the `Builder::formatter` method and the `Formatter` type to select + which tool will be used to format the bindings. (#2453) + * Added the `Builder::emit_diagnostics` method and the `--emit-diagnostics` + flag to enable emission of diagnostic messages under the `experimental` + feature. (#2436) + * Added support for the `"efiapi"` calling convention (#2490). + * Added the `ParseCallbacks::read_env_var` method which runs everytime + `bindgen` reads and environment variable. (#2400) + * Added the `ParseCallbacks::generated_link_name_override` method which allow + overriding the link name of items. (#2425) + * Add support for C `enum`s when generating code while using the + `--wrap-static-fns` feature. (#2415) + +## Changed + * Static functions with no arguments use `void` as their single argument + instead of having no arguments when the `--wrap-static-fns` flag is used. + (#2443) + * The source file generated when the `--wrap-static-fns` flag is enabled now + contains `#include` directives with all the input headers and all the source + code added with the `header_contents` method. (#2447) + * The source file generated when the `--wrap-static-fns` flag no longer uses + `asm` labeling and the link name of static wrapper functions is allowed to + be mangled. (#2448) + * The documentation of the generated `type` aliases now matches the comments + of their `typedef` counterparts instead of using the comments of the aliased + 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) + * The `Bindings::emit_warnings` and `Bindings::warnings` methods were removed + in favor of `--emit-diagnostics`. (#2436) + * Bindgen no longer generates C string constants that cannot be represented as + byte slices. (#2487) + +# 0.64.0 + +## Added + * Added a new set of flags `--with-derive-custom`, + `--with-derive-custom-struct`, `--with-derive-custom-enum` and + `--with-derive-custom-enum` to add custom derives from the CLI. + * Added the `--experimental` flag on `bindgen-cli` and the `experimental` + feature on `bindgen` to gate experimental features whose implementation is + incomplete or are prone to change in a non-backwards compatible manner. + * Added a new set of flags and their equivalent builder methods + `--wrap-static-fns`, `--wrap-static-fns-suffix` and `--wrap-static-fns-path` + to generate C function wrappers for `static` or `static inline` functions. + This feature is experimental. + +## Changed + * Fixed name collisions when having a C `enum` and a `typedef` with the same + name. + * The `ParseCallbacks::generated_name_override` method now receives `ItemInfo<'_>` as + argument instead of a `&str`. + * Updated the `clang-sys` crate version to 1.4.0 to support clang 15. + * The return type is now omitted in signatures of functions returning `void`. + * Updated the `clap` dependency for `bindgen-cli` to 4. + * Rewrote the `bindgen-cli` argument parser which could introduce unexpected + behavior changes. + * The `ParseCallbacks::add_derives` method now receives `DeriveInfo<'_>` as + argument instead of a `&str`. This type also includes the kind of target type. + +# 0.63.0 + +## Added + * new feature: `process_comments` method to the `ParseCallbacks` trait to + handle source code comments. + +## Changed + * Only wrap unsafe operations in unsafe blocks if the `--wrap_unsafe_ops` + option is enabled. + * Replace the `name: &str` argument for `ParseCallbacks::add_derives` by + `info: DeriveInfo`. + * All the rust targets equal or lower than `1.30` are being deprecated and + will be removed in the future. If you have a good reason to use any of these + targets, please report it in the issue tracker. + +## Removed + + * The following deprecated methods and their equivalent CLI arguments were + removed: `whitelist_recursively`, `hide_type`, `blacklist_type`, + `blacklist_function`, `blacklist_item`, `whitelisted_type`, + `whitelist_type`, `whitelist_function`, `whitelisted_function`, + `whitelist_var`, `whitelisted_var`, `unstable_rust`. + +# 0.62.0 + +## Added + + * new feature: `--override-abi` flag to override the ABI used by functions + matching a regular expression. + * new feature: allow using the `C-unwind` ABI in `--override-abi` on nightly + rust. + +## Changed + + * Regex inputs are sanitized so alternation (`a|b`) is handled correctly but + wildcard patterns (`*`) are now considered invalid. The `.*` pattern can be + used as a replacement. + * the `ParseCallbacks`trait does not require to implement `UnwindSafe`. + * the `Builder::parse_callbacks` method no longer overwrites previously added + callbacks and composes them in a last-to-first manner. + * any generated rust code containing unsafe operations inside unsafe functions + is wrapped in unsafe blocks now. + +## Fixed + + * Various issues with upcoming clang/libclang versions have been fixed. + +# 0.61.0 + +Released 2022/10/16 + +## Added + + * new feature: `--sort-semantically` flag to sort the output in a predefined + manner [(#1743)]. + * new feature: `Bindgen::emit_warnings` method to emit warnings to stderr in + build scripts. + * new feature: `--newtype-global-enum` flag to generate enum variants as + global constants. + * new feature: `--default-non-copy-union-style` flag to set the default style + of code used to generate unions with non-`Copy` members. + * new feature: `--bindgen-wrapper-union` flag to mark any union that matches a + regex and has a non-Copy member to use a bindgen-generated wrapper for its + fields. + * new feature: `--manually-drop-union` flag to mark any union that matches a + regex and has a non-`Copy` member to use `ManuallyDrop`. + * new feature: `--merge-extern-blocks` flag to merge several `extern` blocks + that have the same ABI. + * new feature: `--no-size_t-is-usize` flag to not bind `size_t` as `usize`. + * new feature: `Builder` implements `Clone`. + +## Changed + + * clap and regex have been updated, new msrv is 1.57. + * The `--enable-function-attribute-detection` flag is also used to detect + diverging functions so the generated bindings use `!` as the return type. + * The `--size_t-is-usize` flag is enabled by default. + * Unused type aliases for `` types are no longer emitted. + * The `blocklist` options now can be used to block objective-C methods. + * The `core::ffi` module is used the sized raw integer types + instead of `std::os::raw` if the Rust target version is `1.64` or higher and + the `--use-core` flag is enabled. + * The `bindgen` CLI utility must be installed using `cargo install + bindgen-cli` now. + * Using `bindgen` as a library no longer pulls clap and any other CLI + related dependencies. + +## Fixed + + * Const correctness of incomplete arrays has been fixed. (#2301) + * C++ inline namespaces don't panic. (#2294) + +[(#1743)]: https://github.com/rust-lang/rust-bindgen/issues/1743 + +# 0.60.1 + +Released 2022/06/06 + +## Fixed + + * Fixed stack overflow in generated tests for structs with many fields (#2219). + +# 0.60.0 + +Released 2022/06/05 + +## Added + + * Objective-C structs now derive `Debug` and `Copy` to support C and Objective-C structs. [(#2176)][] + * Allow fully-qualified derives. (#2156) + * Bindings generation now returns a more suitable error (#2125) + * `--version --verbose` now prints clang version (#2140). + * Experimental vtable generation (#2145). + * Added an `--allowlist-file` option (#2122). + * Support for vectorcall ABI (#2177). + +## Fixed + + * Fixed lifetimes with Objective-C trait templates. [(#2176)][] + * Fixed objc imports for non-`#[macro_use]` use. [(#2176)][] + * Handle differences between clang and rustc targets for RISCV (#2137). + * `BINDGEN_EXTRA_CLANG_ARGS` is respected on the CLI now (#1723). + * Use common type alias for anonymous enums in consts mode (#2191) + * Look for `#[must_use]` in typedefs (#2206). + * Fixed derive on packed structs (#2083). + * Fixed warnings on layout tests (#2203). + +## Changed + + * cexpr, clap, and nom have been updated, new msrv is 1.54. + +## Removed + + * Support for ancient libclang versions has been removed. + + [(#2176)]: https://github.com/rust-lang/rust-bindgen/pull/2176 + +# 0.59.2 + +Released 2021/11/26 + + * cexpr+env_logger bump. + * Various fixes for C++ crashes / hangs. + * Enums now respect annotations and derives properly in more cases. + * Some more APIs (blocklist-file, etc). + * 'static lifetime is elided when appropriate. + # 0.59.1 Released 2021/07/26 @@ -1037,7 +1591,7 @@ Released 2017/10/27 We <3 folks who [help us find and fix issues via fuzzing][fuzzing]! *hint hint* -* Added experimental support for the `thiscall` ABI when targetting Rust +* Added experimental support for the `thiscall` ABI when targeting Rust nightly. [#1065][] ## Changed @@ -1141,7 +1695,7 @@ Released 2017/10/27 have. [#1094][] [faq]: https://rust-lang.github.io/rust-bindgen/faq.html -[fuzzing]: https://github.com/rust-lang/rust-bindgen/blob/master/csmith-fuzzing/README.md +[fuzzing]: https://github.com/rust-lang/rust-bindgen/blob/main/csmith-fuzzing/README.md [#938]: https://github.com/rust-lang/rust-bindgen/issues/938 [#888]: https://github.com/rust-lang/rust-bindgen/issues/888 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 439a18da58..9c28e198c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,10 +8,11 @@ and introduce yourself. - - [Code of Conduct](#code-of-conduct) - [Filing an Issue](#filing-an-issue) - [Looking to Start Contributing to `bindgen`?](#looking-to-start-contributing-to-bindgen) +- [Prerequisites](#prerequisites) + - [`rustfmt` / `cargo fmt`](#rustfmt--cargo-fmt) - [Building](#building) - [Testing](#testing) - [Overview](#overview) @@ -24,6 +25,7 @@ and introduce yourself. - [Fuzzing `bindgen` with `csmith`](#fuzzing-bindgen-with-csmith) - [Property tests for `bindgen` with `quickchecking`](#property-tests-for-bindgen-with-quickchecking) - [Code Overview](#code-overview) + - [Implementing new options using `syn`](#implementing-new-options-using-syn) - [Pull Requests and Code Reviews](#pull-requests-and-code-reviews) - [Generating Graphviz Dot Files](#generating-graphviz-dot-files) - [Debug Logging](#debug-logging) @@ -31,6 +33,13 @@ and introduce yourself. - [Getting `creduce`](#getting-creduce) - [Isolating Your Test Case](#isolating-your-test-case) - [Writing a Predicate Script](#writing-a-predicate-script) +- [Cutting a new bindgen release](#cutting-a-new-bindgen-release) + - [Updating the changelog](#updating-the-changelog) + - [Merge to `main`](#merge-to-main) + - [Tag and publish](#tag-and-publish) + - [Create a new release on Github](#create-a-new-release-on-github) + - [What to do if a Github release fails](#what-to-do-if-a-github-release-fails) + - [Create a new crates.io release](#create-a-new-cratesio-release) @@ -38,70 +47,72 @@ and introduce yourself. We abide by the [Rust Code of Conduct][coc] and ask that you do as well. -[coc]: https://www.rust-lang.org/en-US/conduct.html +[coc]: https://www.rust-lang.org/policies/code-of-conduct ## Filing an Issue 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](#logs) 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 + +### `rustfmt` / `cargo fmt` + +We use `nightly` channel for `rustfmt`, +so please set the appropriate setting in your editor/IDE for that. + +For rust-analyzer, you can set `rustfmt.extraArgs = ['+nightly']`. + +To check via command line, you can run `cargo +nightly fmt --check`. ## Building 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: - -``` -$ export LIBCLANG_PATH=path/to/clang-9.0/lib -``` - -Additionally, you may want to build and test with the `testing_only_docs` -feature to ensure that you aren't forgetting to document types and functions. CI -will catch it if you forget, but the turn around will be a lot slower ;) +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: -``` -$ cargo build --features testing_only_docs +```sh +export LIBCLANG_PATH=path/to/clang-9.0/lib ``` ## Testing ### Overview -Input C/C++ test headers reside in the `tests/headers` directory. Expected -output Rust bindings live in `tests/expectations/tests`. For example, -`tests/headers/my_header.h`'s expected generated Rust bindings would be -`tests/expectations/tests/my_header.rs`. +Input C/C++ test headers reside in the `bindgen-tests/tests/headers` directory. Expected +output Rust bindings live in `bindgen-tests/tests/expectations/tests`. For example, +`bindgen-tests/tests/headers/my_header.h`'s expected generated Rust bindings would be +`bindgen-tests/tests/expectations/tests/my_header.rs`. There are also some integration tests in the `./bindgen-integration` crate, which uses `bindgen` to 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 run through `rustfmt` before they are -compared. Make sure you have `rustfmt` up to date: - -``` -$ rustup update nightly -$ rustup component add rustfmt --toolchain nightly -``` +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). +Note also that `rustfmt` formatting is disabled for the `bindgen-tests/tests/expectations/` +directory tree, which helps avoid failing ui tests. Note: running `cargo test` from the root directory of `bindgen`'s repository does not automatically test the generated bindings or run the integration tests. @@ -109,11 +120,11 @@ These steps must be performed manually when needed. ### Testing Bindings Generation -To regenerate bindings from the corpus of test headers in `tests/headers` and -compare them against the expected bindings in `tests/expectations/tests`, run: +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 @@ -122,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). @@ -139,27 +150,30 @@ those. ### Testing Generated Bindings If your local changes are introducing expected modifications in the -`tests/expectations/tests/*` bindings files, then you should test that the +`bindgen-tests/tests/expectations/tests/*` bindings files, then you should test that the generated bindings files still compile, and that their struct layout tests still pass. Also, run the integration tests (see below). You can do this with these commands: -``` -$ cd tests/expectations -$ cargo test +```sh +cd bindgen-tests/tests/expectations +cargo test ``` ### Testing a Single Header's Bindings Generation and Compiling its Bindings -Sometimes its useful to work with one test header from start (generating +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 bindings for it) to finish (compiling the bindings and running their layout -tests). This can be done with the `tests/test-one.sh` script. It supports fuzzy +tests). This can be done with the `bindgen-tests/tests/test-one.sh` script. It supports fuzzy searching for test headers. For example, to test `tests/headers/what_is_going_on.hpp`, execute this command: -``` -$ ./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, @@ -167,9 +181,9 @@ you'll need to rebuild it before running the script again. ### Authoring New Tests -To add a new test header to the suite, simply put it in the `tests/headers` +To add a new test header to the suite, simply put it in the `bindgen-tests/tests/headers` directory. Next, run `bindgen` to generate the initial expected output Rust -bindings. Put those in `tests/expectations/tests`. +bindings. Put those in `bindgen-tests/tests/expectations/tests`. If your new test requires certain flags to be passed to `bindgen`, you can specify them at the top of the test header, with a comment like this: @@ -182,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 tests/expectations -$ cargo test new_test_header +```sh +cd bindgen-tests/tests/expectations +cargo test new_test_header ``` ### Test Expectations and `libclang` Versions @@ -192,17 +206,16 @@ $ cargo test new_test_header If a test generates different bindings across different `libclang` versions (for example, because we take advantage of better/newer APIs when possible), then you can add multiple test expectations, one for each supported `libclang` -version. Instead of having a single `tests/expectations/tests/my_test.rs` file, +version. Instead of having a single `bindgen-tests/tests/expectations/tests/my_test.rs` file, add each of: -* `tests/expectations/tests/libclang-9/my_test.rs` -* `tests/expectations/tests/libclang-5/my_test.rs` -* `tests/expectations/tests/libclang-4/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 -many version of `libclang` installed locally. Just make a work-in-progress pull -request, and then when Travis CI fails, it will log a diff of the +many versions of `libclang` installed locally. Just make a work-in-progress pull +request, and then when CI fails, it will log a diff of the expectations. Use the diff to patch the appropriate expectation file locally and then update your pull request. @@ -210,15 +223,9 @@ 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: +```sh +cargo test --features __testing_only_libclang_$VERSION ``` -$ cargo test --features testing_only_libclang_$VERSION -``` - -Where `$VERSION` is one of: - -* `4` -* `3_9` -* `3_8` depending on which version of `libclang` you have installed. @@ -230,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` @@ -249,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 @@ -266,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 @@ -315,14 +322,26 @@ 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. +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` + +If a new option can be implemented using the `syn` crate it should be added to +the `codegen::postprocessing` module by following these steps: + +- Introduce a new field to `BindgenOptions` for the option. +- Write a free function inside `codegen::postprocessing` implementing the + option. This function with the same name of the `BindgenOptions` field. +- Add a new value to the `codegen::postprocessing::PASSES` for the option using + the `pass!` macro. ## Pull Requests and Code Reviews Ensure that each commit stands alone, and passes tests. This enables better `git bisect`ing when needed. If your commits do not stand on their own, then rebase -them on top of the latest master and squash them into a single commit. +them on top of the latest main and squash them into a single commit. All pull requests undergo code review before merging. To request review, comment `r? @github_username_of_reviewer`. They we will respond with `r+` to approve the @@ -331,13 +350,13 @@ changes should be squashed into the original commit. Unsure who to ask for review? Ask any of: -* `@emilio` -* `@fitzgen` +- `@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 @@ -348,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: @@ -375,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 @@ -399,13 +418,13 @@ 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 for building and/or installing `creduce`.](https://github.com/csmith-project/creduce/blob/master/INSTALL) +Otherwise, follow [these instructions](https://github.com/csmith-project/creduce/blob/master/INSTALL.md) for building and/or installing `creduce`. Running `creduce` requires two things: @@ -416,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 @@ -470,10 +491,11 @@ to fail to compile `bindgen`'s emitted bindings, you can invoke `predicate.py` like this: ```bash +# the rustc-grep argument expects a regex, thus escape where necessary path/to/rust-bindgen/csmith-fuzzing/predicate.py \ --bindings-grep NameOfTheStructThatIsErroneouslyDerivingEq \ --expect-compile-fail \ - --rustc-grep 'error[E0277]: the trait bound `f64: std::cmp::Eq` is not satisfied' \ + --rustc-grep 'error\[E0277\]: the trait bound `f64: std::cmp::Eq` is not satisfied' \ ./isolated-test-case.h ``` @@ -490,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. @@ -504,3 +526,101 @@ case down to 5 lines. Happy bug hunting and test case reducing! [More information on using `creduce`.](https://embed.cs.utah.edu/creduce/using/) + +## Cutting a new bindgen release + +To cut a release, the following needs to happen: + +### Updating the changelog + +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: + +```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). +It is very important that you do not rename the `Unreleased` section of the +changelog as this will be done automatically using `cargo release` on a further +step. + +### Merge to `main` + +For regular releases, the changes above should end up in `main` before +publishing. For dot-releases of an old version (e.g., cherry-picking an +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 +``` + +This does the following: + +- Bump the version. +- Turn the `Unreleased` section of the changelog into the section for the version being released. +- Update the table of contents of the changelog using `doctoc`. +- Tag (`git tag`) the HEAD commit +- Push (`git push`) to GitHub + +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** + +> NOTE: +> We use the `--no-publish` so that the crates are only published after the release is complete. +> This is automatic, provided the release CI job is successful. + +### Create a new release on Github + +The release is automated with the help of `.github/workflows/release.yml`, +and will only be created... + +- when a Git tag is pushed +- when all tests succeed + +While the tests are still running, +a draft GitHub release will be created, +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. + +To update the release configuration, +when a new `cargo-dist` is available: + +```sh +cargo dist init # from "cargo install cargo-dist" +``` + +### What to do if a Github release fails + +If the release process fails after you run `cargo release`, you can manually +delete the tag and release from Github. Also remember to delete the tag locally +by running `git tag -d`. Once all the extra changes are in the `main` branch, +you can trigger a release by creating a new tag using `git tag` and push it +using `git push --tag`. + +### Create a new crates.io release + +Go to [the Publish +workflow](https://github.com/rust-lang/rust-bindgen/actions/workflows/publish.yml) +and run a new workflow using the "Run Workflow" button. + +Remember that crates.io releases cannot be deleted! + +[`prettyplease`]: https://github.com/dtolnay/prettyplease diff --git a/Cargo.lock b/Cargo.lock index 3de8f8f5d2..28bc2732ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,58 +4,148 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.15" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] -name = "atty" -version = "0.2.14" +name = "annotate-snippets" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "anstyle", + "unicode-width", ] [[package]] -name = "autocfg" -version = "1.0.1" +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.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +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 = "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.59.2" +version = "0.72.0" dependencies = [ + "annotate-snippets", "bitflags", "cexpr", "clang-sys", "clap", - "diff", - "env_logger", - "lazy_static", - "lazycell", + "clap_complete", + "itertools", "log", - "peeking_take_while", + "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", + "syn", +] + +[[package]] +name = "bindgen-cli" +version = "0.72.0" +dependencies = [ + "bindgen", + "env_logger 0.10.2", + "log", + "proc-macro2", + "shlex", +] + +[[package]] +name = "bindgen-integration" +version = "0.1.0" +dependencies = [ + "bindgen", + "cc", +] + +[[package]] +name = "bindgen-tests" +version = "0.1.0" +dependencies = [ + "bindgen", + "owo-colors", + "prettyplease", + "proc-macro2", + "regex", + "shlex", + "similar", + "syn", "tempfile", - "which", ] [[package]] name = "bitflags" -version = "1.2.1" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "cc" +version = "1.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -68,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.2.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -85,245 +175,352 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.4" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01c9347757e131122b19cd19a05c85805b68c2352a97b623efdc3c295290299" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ - "atty", - "bitflags", - "indexmap", - "os_str_bytes", + "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", "strsim", - "termcolor", - "textwrap", ] [[package]] -name = "diff" -version = "0.1.12" +name = "clap_complete" +version = "4.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb745187d7f4d76267b37485a65e0149edd0e91a4cfcdd3f27524ad86cee9f3" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.6.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] [[package]] name = "env_logger" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", ] +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] name = "glob" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] -name = "hashbrown" -version = "0.11.2" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +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 = "indexmap" -version = "1.7.0" +name = "is-terminal" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "autocfg", - "hashbrown", + "hermit-abi", + "libc", + "windows-sys", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "lazycell" -version = "1.3.0" +name = "itertools" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] [[package]] name = "libc" -version = "0.2.98" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.7.0" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "winapi", + "windows-targets", ] +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "log" -version = "0.4.14" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "malloc_buf" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" dependencies = [ - "cfg-if", + "libc", ] [[package]] name = "memchr" -version = "2.4.1" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "minimal-lexical" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nom" -version = "7.0.0" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", - "version_check", ] [[package]] -name = "os_str_bytes" -version = "6.0.0" +name = "objc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ - "memchr", + "malloc_buf", ] [[package]] -name = "peeking_take_while" -version = "0.1.2" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "ppv-lite86" -version = "0.2.10" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] -name = "proc-macro2" -version = "1.0.28" +name = "owo-colors" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" -dependencies = [ - "unicode-xid", -] +checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" [[package]] -name = "quote" -version = "1.0.9" +name = "prettyplease" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", + "syn", ] [[package]] -name = "rand" -version = "0.8.4" +name = "proc-macro2" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "unicode-ident", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "quickcheck" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ - "ppv-lite86", - "rand_core", + "env_logger 0.8.4", + "log", + "rand", ] [[package]] -name = "rand_core" -version = "0.6.3" +name = "quickchecking" +version = "0.0.0" +dependencies = [ + "clap", + "quickcheck", + "tempfile", +] + +[[package]] +name = "quote" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ - "getrandom", + "proc-macro2", ] [[package]] -name = "rand_hc" -version = "0.3.1" +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" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "rand_core", ] [[package]] -name = "redox_syscall" -version = "0.2.9" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "bitflags", + "getrandom 0.2.16", ] [[package]] name = "regex" -version = "1.4.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -332,30 +529,40 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "winapi", + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "shlex" -version = "1.0.0" +name = "similar" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "strsim" @@ -363,91 +570,168 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" -version = "3.2.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys", ] [[package]] name = "termcolor" -version = "1.1.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] -name = "textwrap" -version = "0.14.2" +name = "tests_expectations" +version = "0.0.0" +dependencies = [ + "block", + "libloading", + "objc", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-width" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] -name = "version_check" -version = "0.9.3" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "which" -version = "4.2.1" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc009ab82a2afc94b9e467ab4214aee9cad1356cd9191264203d7d72006e00d" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "either", - "lazy_static", - "libc", + "wit-bindgen-rt", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-sys", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "winapi", + "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 = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] diff --git a/Cargo.toml b/Cargo.toml index cec8a57902..edb0d35371 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,86 +1,98 @@ -[package] -authors = [ - "Jyun-Yan You ", - "Emilio Cobos Álvarez ", - "Nick Fitzgerald ", - "The Servo project developers", +[workspace] +resolver = "2" +members = [ + "bindgen", + "bindgen-cli", + "bindgen-integration", + "bindgen-tests", + "bindgen-tests/tests/quickchecking", + "bindgen-tests/tests/expectations", ] -description = "Automatically generates Rust FFI bindings to C and C++ libraries." -keywords = ["bindings", "ffi", "code-generation"] -categories = ["external-ffi-bindings", "development-tools::ffi"] -license = "BSD-3-Clause" -name = "bindgen" -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.59.2" -edition = "2018" -build = "build.rs" - -include = [ - "LICENSE", - "README.md", - "Cargo.toml", - "build.rs", - "src/*.rs", - "src/**/*.rs", +default-members = [ + "bindgen", + "bindgen-cli", + "bindgen-tests", ] -[badges] -travis-ci = { repository = "rust-lang/rust-bindgen" } - -[lib] -path = "src/lib.rs" - -[[bin]] -name = "bindgen" -path = "src/main.rs" -doc = false -required-features = ["clap"] - -[dev-dependencies] -diff = "0.1" -clap = "3" -shlex = "1" -tempfile = "3" +[workspace.package] +# If you change this, also update README.md +rust-version = "1.70.0" +edition = "2021" -[dependencies] -bitflags = "1.0.3" +# 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" -# This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 -clap = { version = "3", optional = true } -clang-sys = { version = "1", features = ["clang_6_0"] } -lazycell = "1" -lazy_static = "1" -peeking_take_while = "0.1.2" +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.0", default-features = false , features = [ "std", "unicode"]} -which = { version = "4.2.1", optional = true, default-features = false } +regex = { version = "1.5.3", default-features = false } +rustc-hash = "2.1.0" shlex = "1" -rustc-hash = "1.0.1" -proc-macro2 = { version = "1", default-features = false } +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" -[dependencies.env_logger] -optional = true -version = "0.9.0" +# TODO +trivially_copy_pass_by_ref = "allow" +unused_self = "allow" -[dependencies.log] -optional = true -version = "0.4" +# Theese seem to be ok to ignore for now +enum_glob_use = "allow" +too_many_lines = "allow" -[features] -default = ["logging", "clap", "runtime", "which-rustfmt"] -logging = ["env_logger", "log"] -static = ["clang-sys/static"] -runtime = ["clang-sys/runtime"] -# Dynamically discover a `rustfmt` binary using the `which` crate -which-rustfmt = ["which"] +# Config for 'cargo release' +[workspace.metadata.release] +shared-version = true # ensures published packages share the same version +tag-name = "v{{version}}" +# Don't release any crate unless its manifest has `release = true` +release = false -# These features only exist for CI testing -- don't use them if you're not hacking -# on bindgen! -testing_only_docs = [] -testing_only_extra_assertions = [] -testing_only_libclang_9 = [] -testing_only_libclang_5 = [] -testing_only_libclang_4 = [] +# The profile that 'cargo dist' will build with +[profile.dist] +inherits = "release" +lto = "thin" diff --git a/README.md b/README.md index 4b1194fa2e..b35dee3bef 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,16 @@ extern "C" { ## MSRV -The minimum supported Rust version is **1.54**. +The `bindgen` minimum supported Rust version is **1.70.0**. + +The `bindgen-cli` minimum supported Rust version is **1.70.0**. No MSRV bump policy has been established yet, so MSRV may increase in any release. +The MSRV is the minimum Rust version that can be used to *compile* each crate. However, `bindgen` and `bindgen-cli` can generate bindings that are compatible with Rust versions below the current MSRV. + +Most of the time, the `bindgen-cli` crate will have a more recent MSRV than `bindgen` as crates such as `clap` require it. + ## API Reference [API reference documentation is on docs.rs](https://docs.rs/bindgen) diff --git a/appveyor.yml b/appveyor.yml index 51129cdcbe..ffb74eedc6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,24 +2,18 @@ environment: RUST_BACKTRACE: 1 RUST_CHANNEL: "%Configuration%" matrix: - - TARGET: gnu - LLVM_VERSION: 4.0.0-1 - BINDGEN_FEATURES: testing_only_libclang_4 - - TARGET: gnu - LLVM_VERSION: 5.0.0-1 - BINDGEN_FEATURES: testing_only_libclang_5 - TARGET: gnu LLVM_VERSION: 9.0.0-1 - BINDGEN_FEATURES: testing_only_libclang_9 - - TARGET: msvc - LLVM_VERSION: 4.0.0 - BINDGEN_FEATURES: testing_only_libclang_4 - - TARGET: msvc - LLVM_VERSION: 5.0.0 - BINDGEN_FEATURES: testing_only_libclang_5 + BINDGEN_FEATURES: __testing_only_libclang_9 + - TARGET: gnu + LLVM_VERSION: 16.0.4 + BINDGEN_FEATURES: __testing_only_libclang_16 - TARGET: msvc LLVM_VERSION: 9.0.0 - BINDGEN_FEATURES: testing_only_libclang_9 + BINDGEN_FEATURES: __testing_only_libclang_9 + - TARGET: msvc + LLVM_VERSION: 16.0.4 + BINDGEN_FEATURES: __testing_only_libclang_16 configuration: - stable @@ -31,7 +25,7 @@ platform: branches: only: - - master + - main install: - if %PLATFORM% == x86 (set RUST_PLATFORM=i686&set MINGW_BITS=32) else (set RUST_PLATFORM=x86_64&set MINGW_BITS=64) diff --git a/bindgen-cli/Cargo.toml b/bindgen-cli/Cargo.toml new file mode 100644 index 0000000000..e5d49a6ecc --- /dev/null +++ b/bindgen-cli/Cargo.toml @@ -0,0 +1,49 @@ +lints.workspace = true + +[package] +authors = [ + "The rust-bindgen project contributors", +] +description = "Automatically generates Rust FFI bindings to C and C++ libraries." +keywords = ["bindings", "ffi", "code-generation"] +categories = ["external-ffi-bindings", "development-tools::ffi"] +license = "BSD-3-Clause" +name = "bindgen-cli" +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.72.0" +rust-version.workspace = true +edition.workspace = true + +[[bin]] +path = "main.rs" +name = "bindgen" + +[dependencies] +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"] +logging = ["bindgen/logging", "dep:env_logger", "dep:log"] +static = ["bindgen/static"] +runtime = ["bindgen/runtime"] +prettyplease = ["bindgen/prettyplease"] + +## The following features are for internal use and they shouldn't be used if +## you're not hacking on bindgen +# Features used for CI testing +__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"] +__testing_only_libclang_9 = ["bindgen/__testing_only_libclang_9"] +__testing_only_libclang_16 = ["bindgen/__testing_only_libclang_16"] + +[package.metadata.release] +release = true + +[package.metadata.dist] +dist = true diff --git a/bindgen-cli/LICENSE b/bindgen-cli/LICENSE new file mode 120000 index 0000000000..ea5b60640b --- /dev/null +++ b/bindgen-cli/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/bindgen-cli/main.rs b/bindgen-cli/main.rs new file mode 100644 index 0000000000..2d8d370ef1 --- /dev/null +++ b/bindgen-cli/main.rs @@ -0,0 +1,74 @@ +use std::env; + +use bindgen::builder_from_flags; + +#[cfg(feature = "logging")] +fn clang_version_check() { + let version = bindgen::clang_version(); + let expected_version = if cfg!(feature = "__testing_only_libclang_16") { + Some((16, 0)) + } else if cfg!(feature = "__testing_only_libclang_9") { + Some((9, 0)) + } else { + None + }; + + log::info!( + "Clang Version: {}, parsed: {:?}", + version.full, + version.parsed + ); + + if expected_version.is_some() { + // assert_eq!(version.parsed, version.parsed); + } +} + +pub fn main() { + #[cfg(feature = "logging")] + env_logger::init(); + + match builder_from_flags(env::args()) { + Ok((builder, output, verbose)) => { + #[cfg(feature = "logging")] + clang_version_check(); + + std::panic::set_hook(Box::new(move |info| { + if verbose { + print_verbose_err(); + } + eprintln!("{info}"); + })); + + 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}"); + std::process::exit(1); + } + }; +} + +fn print_verbose_err() { + eprintln!("Bindgen unexpectedly panicked"); + eprintln!( + "This may be caused by one of the known-unsupported \ + things (https://rust-lang.github.io/rust-bindgen/cpp.html), \ + please modify the bindgen flags to work around it as \ + described in https://rust-lang.github.io/rust-bindgen/cpp.html" + ); + eprintln!( + "Otherwise, please file an issue at \ + https://github.com/rust-lang/rust-bindgen/issues/new" + ); +} diff --git a/bindgen-integration/.gitattributes b/bindgen-integration/.gitattributes new file mode 100644 index 0000000000..d42187e6fe --- /dev/null +++ b/bindgen-integration/.gitattributes @@ -0,0 +1,4 @@ +# Tell Github Linguist to avoid counting these C and C++ test inputs toward +# statistics. +*.h -linguist-detectable +*.cc -linguist-detectable diff --git a/bindgen-integration/Cargo.toml b/bindgen-integration/Cargo.toml index 9dcf1d377b..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,17 +7,17 @@ version = "0.1.0" authors = ["Emilio Cobos Álvarez "] publish = false build = "build.rs" +rust-version.workspace = true +edition.workspace = true [build-dependencies] -bindgen = { path = ".." } -cc = "1.0" +bindgen = { workspace = true, default-features = true, features = ["experimental"] } +cc.workspace = true [features] static = ["bindgen/static"] runtime = ["bindgen/runtime"] -testing_only_docs = ["bindgen/testing_only_docs"] -testing_only_extra_assertions = ["bindgen/testing_only_extra_assertions"] -testing_only_libclang_9 = ["bindgen/testing_only_libclang_9"] -testing_only_libclang_5 = ["bindgen/testing_only_libclang_5"] -testing_only_libclang_4 = ["bindgen/testing_only_libclang_4"] +__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"] +__testing_only_libclang_9 = ["bindgen/__testing_only_libclang_9"] +__testing_only_libclang_16 = ["bindgen/__testing_only_libclang_16"] diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index d0ec3bc0dd..1b7c2b3b82 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -1,8 +1,10 @@ extern crate bindgen; -extern crate cc; -use bindgen::callbacks::{IntKind, MacroParsingBehavior, ParseCallbacks}; -use bindgen::{Builder, EnumVariation}; +use bindgen::callbacks::{ + DeriveInfo, IntKind, ItemInfo, MacroParsingBehavior, ParseCallbacks, Token, + TokenKind, +}; +use bindgen::{Builder, EnumVariation, Formatter}; use std::collections::HashSet; use std::env; use std::path::PathBuf; @@ -26,21 +28,14 @@ impl ParseCallbacks for MacroCallback { MacroParsingBehavior::Default } - fn item_name(&self, original_item_name: &str) -> Option { - if original_item_name.starts_with("my_prefixed_") { - Some( - original_item_name - .trim_start_matches("my_prefixed_") - .to_string(), - ) - } else if original_item_name.starts_with("MY_PREFIXED_") { - Some( - original_item_name - .trim_start_matches("MY_PREFIXED_") - .to_string(), - ) - } else { - None + fn int_macro(&self, name: &str, _value: i64) -> Option { + match name { + "TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom { + name: "crate::MacroInteger", + is_signed: true, + }), + + _ => None, } } @@ -65,17 +60,6 @@ impl ParseCallbacks for MacroCallback { } } - fn int_macro(&self, name: &str, _value: i64) -> Option { - match name { - "TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom { - name: "crate::MacroInteger", - is_signed: true, - }), - - _ => None, - } - } - fn func_macro(&self, name: &str, value: &[&[u8]]) { match name { "TESTMACRO_NONFUNCTIONAL" => { @@ -115,25 +99,97 @@ 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, item_info: ItemInfo) -> Option { + if item_info.name.starts_with("my_prefixed_") { + Some( + item_info + .name + .trim_start_matches("my_prefixed_") + .to_string(), + ) + } else if item_info.name.starts_with("MY_PREFIXED_") { + Some( + item_info + .name + .trim_start_matches("MY_PREFIXED_") + .to_string(), + ) + } else { + None + } + } + // Test the "custom derives" capability by adding `PartialEq` to the `Test` struct. - fn add_derives(&self, name: &str) -> Vec { - if name == "Test" { - vec![ - "PartialEq".into(), - ] - } else if name == "MyOrderedEnum" { - vec![ - "std::cmp::PartialOrd".into(), - ] + fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec { + if info.name == "Test" { + vec!["PartialEq".into()] + } else if info.name == "MyOrderedEnum" { + vec!["std::cmp::PartialOrd".into()] + } else if info.name == "TestDeriveOnAlias" { + vec!["std::cmp::PartialEq".into(), "std::cmp::PartialOrd".into()] } else { vec![] } } + + // Test the "custom attributes" capability. + fn add_attributes( + &self, + info: &bindgen::callbacks::AttributeInfo<'_>, + ) -> Vec { + if info.name == "Test" { + vec!["#[cfg_attr(test, derive(PartialOrd))]".into()] + } else { + 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 { @@ -151,7 +207,16 @@ impl Drop for MacroCallback { } } -fn main() { +#[derive(Debug)] +struct WrappedVaListCallback; + +impl ParseCallbacks for WrappedVaListCallback { + fn wrap_as_variadic_fn(&self, name: &str) -> Option { + Some(name.to_owned() + "_wrapped") + } +} + +fn setup_macro_test() { cc::Build::new() .cpp(true) .file("cpp/Test.cc") @@ -162,11 +227,13 @@ fn main() { 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()).unwrap(); + let out_rust_file_relative = out_rust_file + .strip_prefix(env::current_dir().unwrap().parent().unwrap()) + .unwrap(); let out_dep_file = out_path.join("test.d"); let bindings = Builder::default() - .rustfmt_bindings(false) + .formatter(Formatter::None) .enable_cxx_namespaces() .default_enum_style(EnumVariation::Rust { non_exhaustive: false, @@ -184,18 +251,119 @@ fn main() { .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() .expect("Unable to generate bindings"); assert!(macros.read().unwrap().contains("TESTMACRO")); - bindings.write_to_file(&out_rust_file).expect("Couldn't write bindings!"); + bindings + .write_to_file(&out_rust_file) + .expect("Couldn't write bindings!"); - let observed_deps = std::fs::read_to_string(out_dep_file).expect("Couldn't read depfile!"); - let expected_deps = format!("{}: cpp/Test.h include/stub.h", out_rust_file_relative.display()); + let observed_deps = + std::fs::read_to_string(out_dep_file).expect("Couldn't read depfile!"); + let expected_deps = format!( + "{}: cpp/Test.h include/stub.h", + out_rust_file_relative.display() + ); assert_eq!( - observed_deps, - expected_deps, + observed_deps, expected_deps, "including stub via include dir must produce correct dep path", ); } + +fn setup_wrap_static_fns_test() { + // GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090 + // set output directory under /target so it is easy to clean generated files + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let out_rust_file = out_path.join("extern.rs"); + + let input_header_dir = PathBuf::from("../bindgen-tests/tests/headers/") + .canonicalize() + .expect("Cannot canonicalize libdir path"); + let input_header_file_path = input_header_dir.join("wrap-static-fns.h"); + let input_header_file_path_str = input_header_file_path + .to_str() + .expect("Path could not be converted to a str"); + + // generate external bindings with the external .c and .h files + #[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), + )) + .parse_callbacks(Box::new(WrappedVaListCallback)) + .wrap_static_fns(true) + .wrap_static_fns_path( + out_path.join("wrap_static_fns").display().to_string(), + ) + .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}"); + + 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 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"); + + // 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{}", + String::from_utf8_lossy(&clang_output.stderr) + ); + } + + let ar_output = std::process::Command::new("ar") + .arg("rcs") + .arg(lib_path) + .arg(obj_path) + .output() + .expect("`ar` command error"); + + if !ar_output.status.success() { + panic!( + "Could not emit library file:\n{}", + String::from_utf8_lossy(&ar_output.stderr) + ); + } + + bindings + .write_to_file(out_rust_file) + .expect("Could not write bindings to the Rust file"); +} + +fn main() { + setup_macro_test(); + setup_wrap_static_fns_test(); +} diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index eee1974cbc..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 @@ -241,3 +243,19 @@ enum MyOrderedEnum { METER, LIGHTYEAR, }; + +// 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 43f71580d2..8c31121b4b 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -4,11 +4,14 @@ mod bindings { include!(concat!(env!("OUT_DIR"), "/test.rs")); } +mod extern_bindings { + include!(concat!(env!("OUT_DIR"), "/extern.rs")); +} + use std::ffi::CStr; use std::mem; use std::os::raw::c_int; -#[allow(unused)] use bindings::testing::Bar; // This type is generated from module_raw_line. type MacroInteger = isize; @@ -175,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, @@ -251,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::()) } @@ -285,4 +287,79 @@ fn test_custom_derive() { assert!(meter < lightyear); assert!(meter > micron); + + // The `add_derives` callback should have added `#[derive(PartialEq, PartialOrd)]` + // to the `TestDeriveOnAlias` new-type alias. If it didn't, this will fail to compile. + let test1 = unsafe { bindings::TestDeriveOnAlias(5) }; + let test2 = unsafe { bindings::TestDeriveOnAlias(6) }; + assert!(test1 < test2); + assert!(!(test1 > test2)); +} + +#[test] +fn test_custom_attributes() { + // The `add_attributes` callback should have added `#[cfg_attr(test, derive(PartialOrd))])` + // to the `Test` struct. If it didn't, this will fail to compile. + let test1 = unsafe { bindings::Test::new(5) }; + let test2 = unsafe { bindings::Test::new(6) }; + assert!(test1 < test2); +} + +#[test] +fn test_wrap_static_fns() { + // GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090 + unsafe { + let f = extern_bindings::foo(); + assert_eq!(11, f); + + let b = extern_bindings::bar(); + assert_eq!(1, b); + + let t = extern_bindings::takes_ptr(&mut 1); + assert_eq!(2, t); + + extern "C" fn function(x: i32) -> i32 { + x + 1 + } + + let tp = extern_bindings::takes_fn_ptr(Some(function)); + assert_eq!(2, tp); + + let tf = extern_bindings::takes_fn(Some(function)); + assert_eq!(3, tf); + + let ta = extern_bindings::takes_alias(Some(function)); + assert_eq!(4, ta); + + let tq = + extern_bindings::takes_qualified(&(&5 as *const _) as *const _); + assert_eq!(5, tq); + + // 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); + + 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 new file mode 100644 index 0000000000..77a28ca3cb --- /dev/null +++ b/bindgen-tests/Cargo.toml @@ -0,0 +1,28 @@ +lints.workspace = true + +[package] +name = "bindgen-tests" +version = "0.1.0" +publish = false +rust-version.workspace = true +edition.workspace = true + +[dev-dependencies] +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"] +static = ["bindgen/static"] +runtime = ["bindgen/runtime"] + +__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"] +__testing_only_libclang_9 = ["bindgen/__testing_only_libclang_9"] +__testing_only_libclang_16 = ["bindgen/__testing_only_libclang_16"] diff --git a/bindgen-tests/build.rs b/bindgen-tests/build.rs new file mode 100644 index 0000000000..cf929b4b65 --- /dev/null +++ b/bindgen-tests/build.rs @@ -0,0 +1,44 @@ +use std::char; +use std::env; +use std::fs::{self, File}; +use std::io::Write; +use std::path::{Path, PathBuf}; + +pub fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let mut dst = File::create(Path::new(&out_dir).join("tests.rs")).unwrap(); + + let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let headers_dir = manifest_dir.join("tests").join("headers"); + + let Ok(headers) = fs::read_dir(headers_dir) else { + // We may not have headers directory after packaging. + return; + }; + + let entries = + headers.map(|result| result.expect("Couldn't read header file")); + + println!("cargo:rerun-if-changed=tests/headers"); + + for entry in entries { + // 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(); + } + } + + dst.flush().unwrap(); +} diff --git a/tests/expectations/src/lib.rs b/bindgen-tests/src/lib.rs similarity index 100% rename from tests/expectations/src/lib.rs rename to bindgen-tests/src/lib.rs diff --git a/bindgen-tests/tests/.gitattributes b/bindgen-tests/tests/.gitattributes new file mode 100644 index 0000000000..96122eb1da --- /dev/null +++ b/bindgen-tests/tests/.gitattributes @@ -0,0 +1,4 @@ +# Tell Github Linguist to avoid counting these C and C++ test inputs toward +# statistics. +*.h -linguist-detectable +*.hpp -linguist-detectable diff --git a/bindgen-tests/tests/expectations/Cargo.toml b/bindgen-tests/tests/expectations/Cargo.toml new file mode 100644 index 0000000000..975fd16678 --- /dev/null +++ b/bindgen-tests/tests/expectations/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "tests_expectations" +description = "bindgen results when ran on ../headers/*" +version = "0.0.0" +authors = [ + "Jyun-Yan You ", + "Emilio Cobos Álvarez ", + "The Servo project developers", +] +publish = false +rust-version.workspace = true +edition.workspace = true + +[dependencies] +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 new file mode 100644 index 0000000000..f4ded7e12d --- /dev/null +++ b/bindgen-tests/tests/expectations/build.rs @@ -0,0 +1,61 @@ +//! Generate a module with a custom `#[path=...]` for each of the files in our +//! libclang version-specific test expectations so that they get their layout +//! tests run. We need to do this because cargo doesn't automatically detect +//! tests subdirectories. + +use std::env; +use std::fs; +use std::io::Write; +use std::path::Path; + +const LIBCLANG_VERSION_DIRS: &[&str] = &["libclang-9"]; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + let mut test_string = String::new(); + + for dir in LIBCLANG_VERSION_DIRS { + let dir = Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()) + .join("tests") + .join(dir); + + println!("cargo:rerun-if-changed={}", dir.display()); + + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + let path = path.canonicalize().unwrap_or(path); + if path.extension().map(|e| e.to_string_lossy()) != + Some("rs".into()) + { + continue; + } + + println!("cargo:rerun-if-changed={}", path.display()); + + let module_name: String = path + .display() + .to_string() + .chars() + .map(|c| match c { + 'a'..='z' | 'A'..='Z' | '0'..='9' => c, + _ => '_', + }) + .collect(); + + test_string.push_str(&format!( + r###" +#[path = "{}"] +mod {module_name}; +"###, + path.display().to_string().replace('\\', "\\\\"), + )); + } + } + + let out_path = Path::new(&env::var_os("OUT_DIR").unwrap()) + .join("libclang_version_specific_generated_tests.rs"); + let mut test_file = fs::File::create(out_path).unwrap(); + test_file.write_all(test_string.as_bytes()).unwrap(); +} diff --git a/bindgen-tests/tests/expectations/lib.rs b/bindgen-tests/tests/expectations/lib.rs new file mode 100755 index 0000000000..e69de29bb2 diff --git a/bindgen-tests/tests/expectations/rustfmt.toml b/bindgen-tests/tests/expectations/rustfmt.toml new file mode 100644 index 0000000000..85a7173599 --- /dev/null +++ b/bindgen-tests/tests/expectations/rustfmt.toml @@ -0,0 +1,2 @@ +# disable rustfmt for this crate so running `cargo fmt` doesn't affect the expected binding files +disable_all_formatting = true diff --git a/tests/expectations/struct_with_anon_struct_array_float.rs b/bindgen-tests/tests/expectations/src/lib.rs similarity index 100% rename from tests/expectations/struct_with_anon_struct_array_float.rs rename to bindgen-tests/tests/expectations/src/lib.rs diff --git a/bindgen-tests/tests/expectations/struct_with_anon_struct_array_float.rs b/bindgen-tests/tests/expectations/struct_with_anon_struct_array_float.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/bindgen-tests/tests/expectations/struct_with_anon_struct_array_float.rs @@ -0,0 +1 @@ + diff --git a/bindgen-tests/tests/expectations/tests/.gitattributes b/bindgen-tests/tests/expectations/tests/.gitattributes new file mode 100644 index 0000000000..9699dfa001 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/.gitattributes @@ -0,0 +1,2 @@ +# Prevent Github Linguist from counting generated files in statistics. +*.rs linguist-generated diff --git a/bindgen-tests/tests/expectations/tests/16-byte-alignment.rs b/bindgen-tests/tests/expectations/tests/16-byte-alignment.rs new file mode 100644 index 0000000000..c55d0b075b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/16-byte-alignment.rs @@ -0,0 +1,184 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +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(Copy, Clone)] +pub union rte_ipv4_tuple__bindgen_ty_1 { + pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, + pub sctp_tag: u32, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1 { + pub dport: u16, + pub sport: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1::dport", + ][::std::mem::offset_of!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, dport) + - 0usize]; + [ + "Offset of field: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1::sport", + ][::std::mem::offset_of!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, sport) + - 2usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_ipv4_tuple__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_ipv4_tuple__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ipv4_tuple__bindgen_ty_1::sctp_tag", + ][::std::mem::offset_of!(rte_ipv4_tuple__bindgen_ty_1, sctp_tag) - 0usize]; +}; +impl Default for rte_ipv4_tuple__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ipv4_tuple"][::std::mem::size_of::() - 12usize]; + ["Alignment of rte_ipv4_tuple"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ipv4_tuple::src_addr", + ][::std::mem::offset_of!(rte_ipv4_tuple, src_addr) - 0usize]; + [ + "Offset of field: rte_ipv4_tuple::dst_addr", + ][::std::mem::offset_of!(rte_ipv4_tuple, dst_addr) - 4usize]; +}; +impl Default for rte_ipv4_tuple { + 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(Copy, Clone)] +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(Copy, Clone)] +pub union rte_ipv6_tuple__bindgen_ty_1 { + pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, + pub sctp_tag: u32, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1 { + pub dport: u16, + pub sport: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1::dport", + ][::std::mem::offset_of!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, dport) + - 0usize]; + [ + "Offset of field: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1::sport", + ][::std::mem::offset_of!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, sport) + - 2usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_ipv6_tuple__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_ipv6_tuple__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ipv6_tuple__bindgen_ty_1::sctp_tag", + ][::std::mem::offset_of!(rte_ipv6_tuple__bindgen_ty_1, sctp_tag) - 0usize]; +}; +impl Default for rte_ipv6_tuple__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ipv6_tuple"][::std::mem::size_of::() - 36usize]; + ["Alignment of rte_ipv6_tuple"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ipv6_tuple::src_addr", + ][::std::mem::offset_of!(rte_ipv6_tuple, src_addr) - 0usize]; + [ + "Offset of field: rte_ipv6_tuple::dst_addr", + ][::std::mem::offset_of!(rte_ipv6_tuple, dst_addr) - 16usize]; +}; +impl Default for rte_ipv6_tuple { + 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)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub union rte_thash_tuple { + pub v4: rte_ipv4_tuple, + pub v6: rte_ipv6_tuple, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_thash_tuple"][::std::mem::size_of::() - 48usize]; + [ + "Alignment of rte_thash_tuple", + ][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: rte_thash_tuple::v4", + ][::std::mem::offset_of!(rte_thash_tuple, v4) - 0usize]; + [ + "Offset of field: rte_thash_tuple::v6", + ][::std::mem::offset_of!(rte_thash_tuple, v6) - 0usize]; +}; +impl Default for rte_thash_tuple { + 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/381-decltype-alias.rs b/bindgen-tests/tests/expectations/tests/381-decltype-alias.rs new file mode 100644 index 0000000000..ed893c21df --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/381-decltype-alias.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct std_allocator_traits { + pub _address: u8, +} +pub type std_allocator_traits___size_type<_Alloc> = _Alloc; diff --git a/bindgen-tests/tests/expectations/tests/abi-override.rs b/bindgen-tests/tests/expectations/tests/abi-override.rs new file mode 100644 index 0000000000..369bfd8d32 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/abi-override.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target = "i686-pc-windows-msvc")] +unsafe extern "fastcall" { + pub fn foo(); +} +unsafe extern "stdcall" { + pub fn bar(); +} +unsafe extern "C" { + pub fn baz(); +} +unsafe extern "system" { + pub fn qux(); +} +pub type boo = ::std::option::Option; +pub type foobar = ::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 new file mode 100644 index 0000000000..b57ddafd32 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/abi_variadic_function.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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/accessors.rs b/bindgen-tests/tests/expectations/tests/accessors.rs new file mode 100644 index 0000000000..586edf2d79 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/accessors.rs @@ -0,0 +1,228 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct SomeAccessors { + pub mNoAccessor: ::std::os::raw::c_int, + ///
+ pub mBothAccessors: ::std::os::raw::c_int, + ///
+ pub mUnsafeAccessors: ::std::os::raw::c_int, + ///
+ pub mImmutableAccessor: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of SomeAccessors"][::std::mem::size_of::() - 16usize]; + ["Alignment of SomeAccessors"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: SomeAccessors::mNoAccessor", + ][::std::mem::offset_of!(SomeAccessors, mNoAccessor) - 0usize]; + [ + "Offset of field: SomeAccessors::mBothAccessors", + ][::std::mem::offset_of!(SomeAccessors, mBothAccessors) - 4usize]; + [ + "Offset of field: SomeAccessors::mUnsafeAccessors", + ][::std::mem::offset_of!(SomeAccessors, mUnsafeAccessors) - 8usize]; + [ + "Offset of field: SomeAccessors::mImmutableAccessor", + ][::std::mem::offset_of!(SomeAccessors, mImmutableAccessor) - 12usize]; +}; +impl SomeAccessors { + #[inline] + pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mBothAccessors + } + #[inline] + pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mBothAccessors + } + #[inline] + pub unsafe fn get_mUnsafeAccessors(&self) -> &::std::os::raw::c_int { + &self.mUnsafeAccessors + } + #[inline] + pub unsafe fn get_mUnsafeAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mUnsafeAccessors + } + #[inline] + pub fn get_mImmutableAccessor(&self) -> &::std::os::raw::c_int { + &self.mImmutableAccessor + } +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AllAccessors { + pub mBothAccessors: ::std::os::raw::c_int, + pub mAlsoBothAccessors: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllAccessors"][::std::mem::size_of::() - 8usize]; + ["Alignment of AllAccessors"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: AllAccessors::mBothAccessors", + ][::std::mem::offset_of!(AllAccessors, mBothAccessors) - 0usize]; + [ + "Offset of field: AllAccessors::mAlsoBothAccessors", + ][::std::mem::offset_of!(AllAccessors, mAlsoBothAccessors) - 4usize]; +}; +impl AllAccessors { + #[inline] + pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mBothAccessors + } + #[inline] + pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mBothAccessors + } + #[inline] + pub fn get_mAlsoBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mAlsoBothAccessors + } + #[inline] + pub fn get_mAlsoBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mAlsoBothAccessors + } +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AllUnsafeAccessors { + pub mBothAccessors: ::std::os::raw::c_int, + pub mAlsoBothAccessors: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllUnsafeAccessors"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of AllUnsafeAccessors", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: AllUnsafeAccessors::mBothAccessors", + ][::std::mem::offset_of!(AllUnsafeAccessors, mBothAccessors) - 0usize]; + [ + "Offset of field: AllUnsafeAccessors::mAlsoBothAccessors", + ][::std::mem::offset_of!(AllUnsafeAccessors, mAlsoBothAccessors) - 4usize]; +}; +impl AllUnsafeAccessors { + #[inline] + pub unsafe fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mBothAccessors + } + #[inline] + pub unsafe fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mBothAccessors + } + #[inline] + pub unsafe fn get_mAlsoBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mAlsoBothAccessors + } + #[inline] + pub unsafe fn get_mAlsoBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mAlsoBothAccessors + } +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ContradictAccessors { + pub mBothAccessors: ::std::os::raw::c_int, + ///
+ pub mNoAccessors: ::std::os::raw::c_int, + ///
+ pub mUnsafeAccessors: ::std::os::raw::c_int, + ///
+ pub mImmutableAccessor: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContradictAccessors", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of ContradictAccessors", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContradictAccessors::mBothAccessors", + ][::std::mem::offset_of!(ContradictAccessors, mBothAccessors) - 0usize]; + [ + "Offset of field: ContradictAccessors::mNoAccessors", + ][::std::mem::offset_of!(ContradictAccessors, mNoAccessors) - 4usize]; + [ + "Offset of field: ContradictAccessors::mUnsafeAccessors", + ][::std::mem::offset_of!(ContradictAccessors, mUnsafeAccessors) - 8usize]; + [ + "Offset of field: ContradictAccessors::mImmutableAccessor", + ][::std::mem::offset_of!(ContradictAccessors, mImmutableAccessor) - 12usize]; +}; +impl ContradictAccessors { + #[inline] + pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { + &self.mBothAccessors + } + #[inline] + pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mBothAccessors + } + #[inline] + pub unsafe fn get_mUnsafeAccessors(&self) -> &::std::os::raw::c_int { + &self.mUnsafeAccessors + } + #[inline] + pub unsafe fn get_mUnsafeAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mUnsafeAccessors + } + #[inline] + pub fn get_mImmutableAccessor(&self) -> &::std::os::raw::c_int { + &self.mImmutableAccessor + } +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Replaced { + pub mAccessor: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Replaced"][::std::mem::size_of::() - 4usize]; + ["Alignment of Replaced"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Replaced::mAccessor", + ][::std::mem::offset_of!(Replaced, mAccessor) - 0usize]; +}; +impl Replaced { + #[inline] + pub fn get_mAccessor(&self) -> &::std::os::raw::c_int { + &self.mAccessor + } + #[inline] + pub fn get_mAccessor_mut(&mut self) -> &mut ::std::os::raw::c_int { + &mut self.mAccessor + } +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Wrapper { + pub mReplaced: Replaced, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Wrapper"][::std::mem::size_of::() - 4usize]; + ["Alignment of Wrapper"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Wrapper::mReplaced", + ][::std::mem::offset_of!(Wrapper, mReplaced) - 0usize]; +}; +impl Wrapper { + #[inline] + pub fn get_mReplaced(&self) -> &Replaced { + &self.mReplaced + } + #[inline] + pub fn get_mReplaced_mut(&mut self) -> &mut Replaced { + &mut self.mReplaced + } +} diff --git a/bindgen-tests/tests/expectations/tests/alias_comments.rs b/bindgen-tests/tests/expectations/tests/alias_comments.rs new file mode 100644 index 0000000000..31ff72b2c6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/alias_comments.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// This is Struct +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Struct { + /// This is field + pub field: ::std::os::raw::c_int, +} +/// This is AliasToStruct +pub type AliasToStruct = Struct; +/// This is AliasToInt +pub type AliasToInt = ::std::os::raw::c_int; +/// This is AliasToAliasToInt +pub type AliasToAliasToInt = AliasToInt; diff --git a/bindgen-tests/tests/expectations/tests/allowlist-file.rs b/bindgen-tests/tests/expectations/tests/allowlist-file.rs new file mode 100644 index 0000000000..b1fb170de0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist-file.rs @@ -0,0 +1,92 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const SOME_DEFUN: u32 = 123; +unsafe extern "C" { + #[link_name = "\u{1}_Z12SomeFunctionv"] + pub fn SomeFunction(); +} +unsafe extern "C" { + pub static mut someVar: ::std::os::raw::c_int; +} +#[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}_ZN9someClass16somePublicMethodEi"] + pub fn someClass_somePublicMethod(this: *mut someClass, foo: ::std::os::raw::c_int); +} +impl someClass { + #[inline] + pub unsafe fn somePublicMethod(&mut self, foo: ::std::os::raw::c_int) { + someClass_somePublicMethod(self, foo) + } +} +unsafe extern "C" { + pub fn ExternFunction(); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3foo18NamespacedFunctionEv"] + pub fn foo_NamespacedFunction(); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct StructWithAllowlistedDefinition { + pub other: *mut StructWithAllowlistedFwdDecl, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of StructWithAllowlistedDefinition", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of StructWithAllowlistedDefinition", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: StructWithAllowlistedDefinition::other", + ][::std::mem::offset_of!(StructWithAllowlistedDefinition, other) - 0usize]; +}; +impl Default for StructWithAllowlistedDefinition { + 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, Default, Copy, Clone)] +pub struct StructWithAllowlistedFwdDecl { + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of StructWithAllowlistedFwdDecl", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of StructWithAllowlistedFwdDecl", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: StructWithAllowlistedFwdDecl::b", + ][::std::mem::offset_of!(StructWithAllowlistedFwdDecl, b) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AllowlistMe { + pub foo: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistMe"][::std::mem::size_of::() - 4usize]; + ["Alignment of AllowlistMe"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: AllowlistMe::foo", + ][::std::mem::offset_of!(AllowlistMe, foo) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/allowlist-namespaces-basic.rs b/bindgen-tests/tests/expectations/tests/allowlist-namespaces-basic.rs new file mode 100644 index 0000000000..151d03f4a4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist-namespaces-basic.rs @@ -0,0 +1,24 @@ +#![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 outer { + #[allow(unused_imports)] + use self::super::super::root; + pub mod inner { + #[allow(unused_imports)] + use self::super::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Helper { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Helper"][::std::mem::size_of::() - 1usize]; + ["Alignment of Helper"][::std::mem::align_of::() - 1usize]; + }; + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/allowlist-namespaces.rs b/bindgen-tests/tests/expectations/tests/allowlist-namespaces.rs new file mode 100644 index 0000000000..563c97ca1d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist-namespaces.rs @@ -0,0 +1,37 @@ +#![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 outer { + #[allow(unused_imports)] + use self::super::super::root; + pub mod inner { + #[allow(unused_imports)] + use self::super::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Helper { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Helper"][::std::mem::size_of::() - 1usize]; + ["Alignment of Helper"][::std::mem::align_of::() - 1usize]; + }; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Test { + pub helper: root::outer::inner::Helper, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Test"][::std::mem::size_of::() - 1usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: Test::helper", + ][::std::mem::offset_of!(Test, helper) - 0usize]; + }; + } +} diff --git a/tests/expectations/tests/allowlist_basic.rs b/bindgen-tests/tests/expectations/tests/allowlist_basic.rs similarity index 89% rename from tests/expectations/tests/allowlist_basic.rs rename to bindgen-tests/tests/expectations/tests/allowlist_basic.rs index 5bfe42e870..a1c6919739 100644 --- a/tests/expectations/tests/allowlist_basic.rs +++ b/bindgen-tests/tests/expectations/tests/allowlist_basic.rs @@ -1,22 +1,16 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct AllowlistMe { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub foo: ::std::os::raw::c_int, pub bar: AllowlistMe_Inner, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct AllowlistMe_Inner { - pub bar: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub bar: T, } impl Default for AllowlistMe_Inner { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/allowlist_fix.rs b/bindgen-tests/tests/expectations/tests/allowlist_fix.rs new file mode 100644 index 0000000000..772772c56c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist_fix.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub enum Test {} +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 new file mode 100644 index 0000000000..93eab7e147 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist_item.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FooDefault: u32 = 0; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub field: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::field"][::std::mem::offset_of!(Foo, field) - 0usize]; +}; +unsafe extern "C" { + pub fn FooNew(value: ::std::os::raw::c_int) -> Foo; +} diff --git a/bindgen-tests/tests/expectations/tests/allowlist_vars.rs b/bindgen-tests/tests/expectations/tests/allowlist_vars.rs new file mode 100644 index 0000000000..342d904a73 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist_vars.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const NONE: u32 = 0; +pub const FOO: u32 = 5; +pub const FOOB: i32 = -2; +pub const FOOBAR: i32 = -10; diff --git a/bindgen-tests/tests/expectations/tests/allowlist_warnings.rs b/bindgen-tests/tests/expectations/tests/allowlist_warnings.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlist_warnings.rs @@ -0,0 +1 @@ +#![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/allowlisted-item-references-no-hash.rs b/bindgen-tests/tests/expectations/tests/allowlisted-item-references-no-hash.rs new file mode 100644 index 0000000000..6c1d13a837 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlisted-item-references-no-hash.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 NoHash { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoHash"][::std::mem::size_of::() - 1usize]; + ["Alignment of NoHash"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AllowlistMe { + pub a: NoHash, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistMe"][::std::mem::size_of::() - 1usize]; + ["Alignment of AllowlistMe"][::std::mem::align_of::() - 1usize]; + ["Offset of field: AllowlistMe::a"][::std::mem::offset_of!(AllowlistMe, a) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/allowlisted-item-references-no-partialeq.rs b/bindgen-tests/tests/expectations/tests/allowlisted-item-references-no-partialeq.rs new file mode 100644 index 0000000000..b969727dbb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlisted-item-references-no-partialeq.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 NoPartialEq { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoPartialEq"][::std::mem::size_of::() - 1usize]; + ["Alignment of NoPartialEq"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AllowlistMe { + pub a: NoPartialEq, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistMe"][::std::mem::size_of::() - 1usize]; + ["Alignment of AllowlistMe"][::std::mem::align_of::() - 1usize]; + ["Offset of field: AllowlistMe::a"][::std::mem::offset_of!(AllowlistMe, a) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/allowlisted_item_references_no_copy.rs b/bindgen-tests/tests/expectations/tests/allowlisted_item_references_no_copy.rs new file mode 100644 index 0000000000..8c671b4e84 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/allowlisted_item_references_no_copy.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct NoCopy { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoCopy"][::std::mem::size_of::() - 1usize]; + ["Alignment of NoCopy"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct AllowlistMe { + pub a: NoCopy, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistMe"][::std::mem::size_of::() - 1usize]; + ["Alignment of AllowlistMe"][::std::mem::align_of::() - 1usize]; + ["Offset of field: AllowlistMe::a"][::std::mem::offset_of!(AllowlistMe, a) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/annotation_hide.rs b/bindgen-tests/tests/expectations/tests/annotation_hide.rs new file mode 100644 index 0000000000..e79c88214d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/annotation_hide.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone)] +pub struct D { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of D"][::std::mem::size_of::() - 4usize]; + ["Alignment of D"][::std::mem::align_of::() - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct NotAnnotated { + pub f: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NotAnnotated"][::std::mem::size_of::() - 4usize]; + ["Alignment of NotAnnotated"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: NotAnnotated::f", + ][::std::mem::offset_of!(NotAnnotated, f) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/anon-fields-prefix.rs b/bindgen-tests/tests/expectations/tests/anon-fields-prefix.rs new file mode 100644 index 0000000000..2b96804c9b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon-fields-prefix.rs @@ -0,0 +1,73 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union color { + pub u1: color__bindgen_ty_1, + pub u2: color__bindgen_ty_2, + pub v3: [::std::os::raw::c_uchar; 3usize], +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct color__bindgen_ty_1 { + pub r: ::std::os::raw::c_uchar, + pub g: ::std::os::raw::c_uchar, + pub b: ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of color__bindgen_ty_1", + ][::std::mem::size_of::() - 3usize]; + [ + "Alignment of color__bindgen_ty_1", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: color__bindgen_ty_1::r", + ][::std::mem::offset_of!(color__bindgen_ty_1, r) - 0usize]; + [ + "Offset of field: color__bindgen_ty_1::g", + ][::std::mem::offset_of!(color__bindgen_ty_1, g) - 1usize]; + [ + "Offset of field: color__bindgen_ty_1::b", + ][::std::mem::offset_of!(color__bindgen_ty_1, b) - 2usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct color__bindgen_ty_2 { + pub y: ::std::os::raw::c_uchar, + pub u: ::std::os::raw::c_uchar, + pub v: ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of color__bindgen_ty_2", + ][::std::mem::size_of::() - 3usize]; + [ + "Alignment of color__bindgen_ty_2", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: color__bindgen_ty_2::y", + ][::std::mem::offset_of!(color__bindgen_ty_2, y) - 0usize]; + [ + "Offset of field: color__bindgen_ty_2::u", + ][::std::mem::offset_of!(color__bindgen_ty_2, u) - 1usize]; + [ + "Offset of field: color__bindgen_ty_2::v", + ][::std::mem::offset_of!(color__bindgen_ty_2, v) - 2usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of color"][::std::mem::size_of::() - 3usize]; + ["Alignment of color"][::std::mem::align_of::() - 1usize]; + ["Offset of field: color::v3"][::std::mem::offset_of!(color, v3) - 0usize]; +}; +impl Default for color { + 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/anon_enum.rs b/bindgen-tests/tests/expectations/tests/anon_enum.rs new file mode 100644 index 0000000000..c3790a2a24 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_enum.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct Test { + pub foo: ::std::os::raw::c_int, + pub bar: f32, +} +pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Test__bindgen_ty_1 { + T_NONE = 0, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 8usize]; + ["Alignment of Test"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Test::foo"][::std::mem::offset_of!(Test, foo) - 0usize]; + ["Offset of field: Test::bar"][::std::mem::offset_of!(Test, bar) - 4usize]; +}; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Baz { + Foo = 0, + Bar = 1, +} diff --git a/bindgen-tests/tests/expectations/tests/anon_enum_allowlist.rs b/bindgen-tests/tests/expectations/tests/anon_enum_allowlist.rs new file mode 100644 index 0000000000..4b172d7aeb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_enum_allowlist.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const NODE_FLAG_FOO: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_FOO; +pub const NODE_FLAG_BAR: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_BAR; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + NODE_FLAG_FOO = 0, + NODE_FLAG_BAR = 1, +} diff --git a/bindgen-tests/tests/expectations/tests/anon_enum_allowlist_item.rs b/bindgen-tests/tests/expectations/tests/anon_enum_allowlist_item.rs new file mode 100644 index 0000000000..4d28c3abc7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_enum_allowlist_item.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const NODE_FLAG_FOO: _bindgen_ty_1 = 0; +pub const NODE_FLAG_BAR: _bindgen_ty_1 = 1; +pub type _bindgen_ty_1 = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/anon_enum_blocklist.rs b/bindgen-tests/tests/expectations/tests/anon_enum_blocklist.rs new file mode 100644 index 0000000000..28ab3ad786 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_enum_blocklist.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FLAG_Z: _bindgen_ty_2 = 0; +pub const FLAG_W: _bindgen_ty_2 = 1; +pub type _bindgen_ty_2 = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/anon_enum_trait.rs b/bindgen-tests/tests/expectations/tests/anon_enum_trait.rs new file mode 100644 index 0000000000..cfd4d03200 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_enum_trait.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct DataType { + pub _address: u8, +} +pub type DataType_value_type<_Tp> = _Tp; +pub type DataType_work_type<_Tp> = DataType_value_type<_Tp>; +pub type DataType_channel_type<_Tp> = DataType_value_type<_Tp>; +pub type DataType_vec_type<_Tp> = DataType_value_type<_Tp>; +pub const DataType_generic_type: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type; +pub const DataType_depth: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type; +pub const DataType_channels: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type; +pub const DataType_fmt: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type; +pub const DataType_type_: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type; +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum DataType__bindgen_ty_1 { + generic_type = 0, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Foo { + pub _address: u8, +} +pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; +pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo__bindgen_ty_1 { + Bar = 0, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/anon_struct_in_union.rs b/bindgen-tests/tests/expectations/tests/anon_struct_in_union.rs new file mode 100644 index 0000000000..dceca1adf3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_struct_in_union.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct s { + pub u: s__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union s__bindgen_ty_1 { + pub field: s__bindgen_ty_1_inner, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct s__bindgen_ty_1_inner { + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of s__bindgen_ty_1_inner", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of s__bindgen_ty_1_inner", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: s__bindgen_ty_1_inner::b", + ][::std::mem::offset_of!(s__bindgen_ty_1_inner, b) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of s__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + ["Alignment of s__bindgen_ty_1"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: s__bindgen_ty_1::field", + ][::std::mem::offset_of!(s__bindgen_ty_1, field) - 0usize]; +}; +impl Default for s__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of s"][::std::mem::size_of::() - 4usize]; + ["Alignment of s"][::std::mem::align_of::() - 4usize]; + ["Offset of field: s::u"][::std::mem::offset_of!(s, u) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/anon_union.rs b/bindgen-tests/tests/expectations/tests/anon_union.rs new file mode 100644 index 0000000000..d9bf3cf183 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/anon_union.rs @@ -0,0 +1,76 @@ +#![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, +} +impl TErrorResult_UnionState { + pub const 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)] +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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ErrorResult"][::std::mem::size_of::() - 24usize]; + ["Alignment of ErrorResult"][::std::mem::align_of::() - 8usize]; +}; +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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: TErrorResult_open0_int_close0", + ][::std::mem::size_of::() - 24usize]; + [ + "Align of template specialization: TErrorResult_open0_int_close0", + ][::std::mem::align_of::() - 8usize]; +}; diff --git a/tests/expectations/tests/anonymous-template-types.rs b/bindgen-tests/tests/expectations/tests/anonymous-template-types.rs similarity index 91% rename from tests/expectations/tests/anonymous-template-types.rs rename to bindgen-tests/tests/expectations/tests/anonymous-template-types.rs index 14afd6b316..f6c894d8b5 100644 --- a/tests/expectations/tests/anonymous-template-types.rs +++ b/bindgen-tests/tests/expectations/tests/anonymous-template-types.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Foo { - pub t_member: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t_member: T, } impl Default for Foo { fn default() -> Self { @@ -28,8 +22,8 @@ pub struct Bar { #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Quux { - pub v_member: V, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub v_member: V, } impl Default for Quux { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/arg_keyword.rs b/bindgen-tests/tests/expectations/tests/arg_keyword.rs new file mode 100644 index 0000000000..5a48aba011 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/arg_keyword.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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/array-of-zero-sized-types.rs b/bindgen-tests/tests/expectations/tests/array-of-zero-sized-types.rs new file mode 100644 index 0000000000..4630abd275 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/array-of-zero-sized-types.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// This should get an `_address` byte. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Empty { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Empty"][::std::mem::size_of::() - 1usize]; + ["Alignment of Empty"][::std::mem::align_of::() - 1usize]; +}; +/** This should not get an `_address` byte, since each `Empty` gets one, meaning + that this object is addressable.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct HasArrayOfEmpty { + pub empties: [Empty; 10usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of HasArrayOfEmpty"][::std::mem::size_of::() - 10usize]; + ["Alignment of HasArrayOfEmpty"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: HasArrayOfEmpty::empties", + ][::std::mem::offset_of!(HasArrayOfEmpty, empties) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/atomic-constant.rs b/bindgen-tests/tests/expectations/tests/atomic-constant.rs new file mode 100644 index 0000000000..344e632085 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/atomic-constant.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub static mut a: ::std::os::raw::c_int; +} +unsafe extern "C" { + pub static mut b: ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/attribute-custom-cli.rs b/bindgen-tests/tests/expectations/tests/attribute-custom-cli.rs new file mode 100644 index 0000000000..55353116d3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/attribute-custom-cli.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[doc(hidden)] +#[derive(Default)] +pub struct foo_struct { + pub inner: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo_struct"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo_struct"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo_struct::inner", + ][::std::mem::offset_of!(foo_struct, inner) - 0usize]; +}; +#[repr(u32)] +#[cfg_attr(test, derive(PartialOrd, Copy))] +#[derive(Clone, Hash, PartialEq, Eq)] +pub enum foo_enum { + inner = 0, +} +#[repr(C)] +#[doc(hidden)] +#[derive(Clone)] +#[derive(Copy)] +pub union foo_union { + pub fst: ::std::mem::ManuallyDrop<::std::os::raw::c_int>, + pub snd: ::std::mem::ManuallyDrop, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo_union"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo_union"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo_union::fst"][::std::mem::offset_of!(foo_union, fst) - 0usize]; + ["Offset of field: foo_union::snd"][::std::mem::offset_of!(foo_union, snd) - 0usize]; +}; +#[repr(C)] +pub struct non_matching { + pub inner: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of non_matching"][::std::mem::size_of::() - 4usize]; + ["Alignment of non_matching"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: non_matching::inner", + ][::std::mem::offset_of!(non_matching, inner) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/attribute-custom.rs b/bindgen-tests/tests/expectations/tests/attribute-custom.rs new file mode 100644 index 0000000000..6d616d3f3e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/attribute-custom.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Debug)] +pub struct my_type { + pub a: ::std::os::raw::c_int, +} +/**
+
*/ +#[repr(C)] +#[derive(Debug)] +#[derive(Clone)] +pub struct my_type2 { + pub a: ::std::os::raw::c_uint, +} +///
+#[repr(C)] +#[derive(Debug)] +#[derive(Clone)] +pub struct my_type3 { + pub a: ::std::os::raw::c_ulong, +} diff --git a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs new file mode 100644 index 0000000000..ec152e1543 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs @@ -0,0 +1,28 @@ +#![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]; +}; +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; +} +impl Foo { + #[inline] + #[must_use] + pub unsafe fn foo(&mut self, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int { + Foo_foo(self, arg1) + } +} +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 new file mode 100644 index 0000000000..f0fb434bcb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs @@ -0,0 +1,25 @@ +#![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]; +}; +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; +} +impl Foo { + #[inline] + pub unsafe fn foo(&mut self, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int { + Foo_foo(self, arg1) + } +} +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/auto.rs b/bindgen-tests/tests/expectations/tests/auto.rs new file mode 100644 index 0000000000..ba93e7a20b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/auto.rs @@ -0,0 +1,21 @@ +#![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, +} +pub const Foo_kFoo: bool = true; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_Z5Test2v"] + pub fn Test2() -> ::std::os::raw::c_uint; +} diff --git a/tests/expectations/tests/bad-namespace-parenthood-inheritance.rs b/bindgen-tests/tests/expectations/tests/bad-namespace-parenthood-inheritance.rs similarity index 81% rename from tests/expectations/tests/bad-namespace-parenthood-inheritance.rs rename to bindgen-tests/tests/expectations/tests/bad-namespace-parenthood-inheritance.rs index 4d0d6bcd18..9ad8429e3c 100644 --- a/tests/expectations/tests/bad-namespace-parenthood-inheritance.rs +++ b/bindgen-tests/tests/expectations/tests/bad-namespace-parenthood-inheritance.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct std_char_traits { diff --git a/bindgen-tests/tests/expectations/tests/base-to-derived.rs b/bindgen-tests/tests/expectations/tests/base-to-derived.rs new file mode 100644 index 0000000000..22ef4fdb08 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/base-to-derived.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct false_type { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of false_type"][::std::mem::size_of::() - 1usize]; + ["Alignment of false_type"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs b/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs new file mode 100644 index 0000000000..2c8d2e5713 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs @@ -0,0 +1,32 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[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 new file mode 100644 index 0000000000..783f0ef7a9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -0,0 +1,1673 @@ +#![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, Default, Copy, Clone)] +pub struct MuchBitfield { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 5usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of MuchBitfield"][::std::mem::size_of::() - 5usize]; + ["Alignment of MuchBitfield"][::std::mem::align_of::() - 1usize]; +}; +impl MuchBitfield { + #[inline] + pub fn m0(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_m0(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m1(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m2(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m3(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m4(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m5(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m6(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m7(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m8(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m9(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m10(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m11(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m12(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m13(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m14(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m15(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m16(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m17(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m18(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m19(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m20(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m21(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m22(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m23(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m24(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m25(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m26(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m27(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(27usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m28(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(28usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m29(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(29usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m30(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(30usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m31(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m32(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 1u8, val as u64) + } + } + #[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, + m2: ::std::os::raw::c_char, + m3: ::std::os::raw::c_char, + m4: ::std::os::raw::c_char, + m5: ::std::os::raw::c_char, + m6: ::std::os::raw::c_char, + m7: ::std::os::raw::c_char, + m8: ::std::os::raw::c_char, + m9: ::std::os::raw::c_char, + m10: ::std::os::raw::c_char, + m11: ::std::os::raw::c_char, + m12: ::std::os::raw::c_char, + m13: ::std::os::raw::c_char, + m14: ::std::os::raw::c_char, + m15: ::std::os::raw::c_char, + m16: ::std::os::raw::c_char, + m17: ::std::os::raw::c_char, + m18: ::std::os::raw::c_char, + m19: ::std::os::raw::c_char, + m20: ::std::os::raw::c_char, + m21: ::std::os::raw::c_char, + m22: ::std::os::raw::c_char, + m23: ::std::os::raw::c_char, + m24: ::std::os::raw::c_char, + m25: ::std::os::raw::c_char, + m26: ::std::os::raw::c_char, + m27: ::std::os::raw::c_char, + m28: ::std::os::raw::c_char, + m29: ::std::os::raw::c_char, + m30: ::std::os::raw::c_char, + m31: ::std::os::raw::c_char, + m32: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 5usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let m0: u8 = unsafe { ::std::mem::transmute(m0) }; + m0 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let m1: u8 = unsafe { ::std::mem::transmute(m1) }; + m1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let m2: u8 = unsafe { ::std::mem::transmute(m2) }; + m2 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 1u8, + { + let m3: u8 = unsafe { ::std::mem::transmute(m3) }; + m3 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 1u8, + { + let m4: u8 = unsafe { ::std::mem::transmute(m4) }; + m4 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 5usize, + 1u8, + { + let m5: u8 = unsafe { ::std::mem::transmute(m5) }; + m5 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 6usize, + 1u8, + { + let m6: u8 = unsafe { ::std::mem::transmute(m6) }; + m6 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 7usize, + 1u8, + { + let m7: u8 = unsafe { ::std::mem::transmute(m7) }; + m7 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 1u8, + { + let m8: u8 = unsafe { ::std::mem::transmute(m8) }; + m8 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 1u8, + { + let m9: u8 = unsafe { ::std::mem::transmute(m9) }; + m9 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 10usize, + 1u8, + { + let m10: u8 = unsafe { ::std::mem::transmute(m10) }; + m10 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 11usize, + 1u8, + { + let m11: u8 = unsafe { ::std::mem::transmute(m11) }; + m11 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 12usize, + 1u8, + { + let m12: u8 = unsafe { ::std::mem::transmute(m12) }; + m12 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 13usize, + 1u8, + { + let m13: u8 = unsafe { ::std::mem::transmute(m13) }; + m13 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 1u8, + { + let m14: u8 = unsafe { ::std::mem::transmute(m14) }; + m14 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 15usize, + 1u8, + { + let m15: u8 = unsafe { ::std::mem::transmute(m15) }; + m15 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 1u8, + { + let m16: u8 = unsafe { ::std::mem::transmute(m16) }; + m16 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 17usize, + 1u8, + { + let m17: u8 = unsafe { ::std::mem::transmute(m17) }; + m17 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 18usize, + 1u8, + { + let m18: u8 = unsafe { ::std::mem::transmute(m18) }; + m18 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 19usize, + 1u8, + { + let m19: u8 = unsafe { ::std::mem::transmute(m19) }; + m19 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 20usize, + 1u8, + { + let m20: u8 = unsafe { ::std::mem::transmute(m20) }; + m20 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 21usize, + 1u8, + { + let m21: u8 = unsafe { ::std::mem::transmute(m21) }; + m21 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 22usize, + 1u8, + { + let m22: u8 = unsafe { ::std::mem::transmute(m22) }; + m22 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 23usize, + 1u8, + { + let m23: u8 = unsafe { ::std::mem::transmute(m23) }; + m23 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 24usize, + 1u8, + { + let m24: u8 = unsafe { ::std::mem::transmute(m24) }; + m24 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 25usize, + 1u8, + { + let m25: u8 = unsafe { ::std::mem::transmute(m25) }; + m25 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 26usize, + 1u8, + { + let m26: u8 = unsafe { ::std::mem::transmute(m26) }; + m26 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 27usize, + 1u8, + { + let m27: u8 = unsafe { ::std::mem::transmute(m27) }; + m27 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 28usize, + 1u8, + { + let m28: u8 = unsafe { ::std::mem::transmute(m28) }; + m28 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 29usize, + 1u8, + { + let m29: u8 = unsafe { ::std::mem::transmute(m29) }; + m29 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 30usize, + 1u8, + { + let m30: u8 = unsafe { ::std::mem::transmute(m30) }; + m30 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 31usize, + 1u8, + { + let m31: u8 = unsafe { ::std::mem::transmute(m31) }; + m31 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 32usize, + 1u8, + { + let m32: u8 = unsafe { ::std::mem::transmute(m32) }; + m32 as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/tests/expectations/tests/bitfield-enum-basic.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs similarity index 88% rename from tests/expectations/tests/bitfield-enum-basic.rs rename to bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs index b6c25870b0..aecb9dc639 100644 --- a/tests/expectations/tests/bitfield-enum-basic.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs @@ -1,20 +1,8 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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 { @@ -48,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 { @@ -154,16 +136,8 @@ impl ::std::ops::BitAndAssign for Dummy__bindgen_ty_1 { #[repr(transparent)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Dummy__bindgen_ty_1(pub ::std::os::raw::c_uint); -#[test] -fn bindgen_test_layout_Dummy() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Dummy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Dummy)) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Dummy"][::std::mem::size_of::() - 1usize]; + ["Alignment of Dummy"][::std::mem::align_of::() - 1usize]; +}; diff --git a/tests/expectations/tests/bitfield-enum-repr-c.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs similarity index 84% rename from tests/expectations/tests/bitfield-enum-repr-c.rs rename to bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs index 1f0228e8e6..df5a69eddd 100644 --- a/tests/expectations/tests/bitfield-enum-repr-c.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs @@ -1,20 +1,8 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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 { @@ -43,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/tests/expectations/tests/bitfield-enum-repr-transparent.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs similarity index 85% rename from tests/expectations/tests/bitfield-enum-repr-transparent.rs rename to bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs index 53e113ed5e..df5a69eddd 100644 --- a/tests/expectations/tests/bitfield-enum-repr-transparent.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs @@ -1,20 +1,8 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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 new file mode 100644 index 0000000000..5d614ab936 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield-large.rs @@ -0,0 +1,322 @@ +#![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)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct HasBigBitfield { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of HasBigBitfield"][::std::mem::size_of::() - 16usize]; + ["Alignment of HasBigBitfield"][::std::mem::align_of::() - 16usize]; +}; +impl HasBigBitfield { + #[inline] + pub fn x(&self) -> i128 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 128u8) as u128) } + } + #[inline] + pub fn set_x(&mut self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 128u8, val as u64) + } + } + #[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 + .set( + 0usize, + 128u8, + { + let x: u128 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct HasTwoBigBitfields { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of HasTwoBigBitfields", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of HasTwoBigBitfields", + ][::std::mem::align_of::() - 16usize]; +}; +impl HasTwoBigBitfields { + #[inline] + pub fn x(&self) -> i128 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 80u8) as u128) } + } + #[inline] + pub fn set_x(&mut self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 80u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_y(&mut self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + self._bitfield_1.set(80usize, 48u8, val as u64) + } + } + #[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 + .set( + 0usize, + 80u8, + { + let x: u128 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 80usize, + 48u8, + { + let y: u128 = unsafe { ::std::mem::transmute(y) }; + y as u64 + }, + ); + __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 new file mode 100644 index 0000000000..3e676c53b5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs @@ -0,0 +1,250 @@ +#![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, Default, Copy, Clone)] +pub struct Test { + pub foo: u64, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, +} +impl Test { + #[inline] + pub fn x(&self) -> u64 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 56u8) as u64) } + } + #[inline] + pub fn set_x(&mut self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 56u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_y(&mut self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(56usize, 8u8, val as u64) + } + } + #[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 + .set( + 0usize, + 56u8, + { + let x: u64 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 56usize, + 8u8, + { + let y: u64 = unsafe { ::std::mem::transmute(y) }; + y as u64 + }, + ); + __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 new file mode 100644 index 0000000000..09ca005589 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs @@ -0,0 +1,241 @@ +#![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, Default, Copy, Clone)] +pub struct Foo { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +#[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}_ZN3Foo4typeEv"] + pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo9set_type_Ec"] + pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo8set_typeEc"] + pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); +} +impl Foo { + #[inline] + pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) } + } + #[inline] + pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[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]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let type__bindgen_bitfield: u8 = unsafe { + ::std::mem::transmute(type__bindgen_bitfield) + }; + type__bindgen_bitfield as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { + Foo_type(self) + } + #[inline] + pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type_(self, c) + } + #[inline] + pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type(self, c) + } +} 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 new file mode 100644 index 0000000000..0c70917fc5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -0,0 +1,1513 @@ +#![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, Default, Copy, Clone)] +pub struct A { + pub _bindgen_align: [u32; 0], + pub x: ::std::os::raw::c_uchar, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub y: ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 4usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::x"][::std::mem::offset_of!(A, x) - 0usize]; + ["Offset of field: A::y"][::std::mem::offset_of!(A, y) - 3usize]; +}; +impl A { + #[inline] + pub fn b1(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b3(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b4(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b5(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b6(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b7(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b8(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b9(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b10(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[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, + b3: ::std::os::raw::c_uint, + b4: ::std::os::raw::c_uint, + b5: ::std::os::raw::c_uint, + b6: ::std::os::raw::c_uint, + b7: ::std::os::raw::c_uint, + b8: ::std::os::raw::c_uint, + b9: ::std::os::raw::c_uint, + b10: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let b3: u32 = unsafe { ::std::mem::transmute(b3) }; + b3 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 1u8, + { + let b4: u32 = unsafe { ::std::mem::transmute(b4) }; + b4 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 1u8, + { + let b5: u32 = unsafe { ::std::mem::transmute(b5) }; + b5 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 5usize, + 1u8, + { + let b6: u32 = unsafe { ::std::mem::transmute(b6) }; + b6 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 6usize, + 1u8, + { + let b7: u32 = unsafe { ::std::mem::transmute(b7) }; + b7 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 7usize, + 1u8, + { + let b8: u32 = unsafe { ::std::mem::transmute(b8) }; + b8 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 1u8, + { + let b9: u32 = unsafe { ::std::mem::transmute(b9) }; + b9 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 1u8, + { + let b10: u32 = unsafe { ::std::mem::transmute(b10) }; + b10 as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 4usize]; + ["Alignment of B"][::std::mem::align_of::() - 4usize]; +}; +impl B { + #[inline] + pub fn foo(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.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.set(0usize, 31u8, val as u64) + } + } + #[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) } + } + #[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) + } + } + #[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, + ) -> __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(Debug, Default, Copy, Clone)] +pub struct C { + pub x: ::std::os::raw::c_uchar, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub baz: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 8usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::x"][::std::mem::offset_of!(C, x) - 0usize]; + ["Offset of field: C::baz"][::std::mem::offset_of!(C, baz) - 4usize]; +}; +impl C { + #[inline] + pub fn b1(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Date1 { + pub _bindgen_align: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub __bindgen_padding_0: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Date1"][::std::mem::size_of::() - 4usize]; + ["Alignment of Date1"][::std::mem::align_of::() - 2usize]; +}; +impl Date1 { + #[inline] + pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } + } + #[inline] + pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[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, + nMonth: ::std::os::raw::c_ushort, + nYear: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 6u8, + { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 5u8, + { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 8u8, + { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Date2 { + pub _bindgen_align: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Date2"][::std::mem::size_of::() - 4usize]; + ["Alignment of Date2"][::std::mem::align_of::() - 2usize]; +}; +impl Date2 { + #[inline] + pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } + } + #[inline] + pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_byte(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[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, + nMonth: ::std::os::raw::c_ushort, + nYear: ::std::os::raw::c_ushort, + byte: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 6u8, + { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 5u8, + { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 8u8, + { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 24usize, + 8u8, + { + let byte: u8 = unsafe { ::std::mem::transmute(byte) }; + byte as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Date3 { + pub _bindgen_align: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub byte: ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Date3"][::std::mem::size_of::() - 4usize]; + ["Alignment of Date3"][::std::mem::align_of::() - 2usize]; + ["Offset of field: Date3::byte"][::std::mem::offset_of!(Date3, byte) - 3usize]; +}; +impl Date3 { + #[inline] + pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } + } + #[inline] + pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[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, + nMonth: ::std::os::raw::c_ushort, + nYear: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 6u8, + { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 5u8, + { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 8u8, + { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs new file mode 100644 index 0000000000..b71bba18ad --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs @@ -0,0 +1,276 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(target_os = "windows"))] +#[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(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum MyEnum { + ONE = 0, + TWO = 1, + THREE = 2, + FOUR = 3, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TaggedPtr { + pub _bindgen_align: [u64; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TaggedPtr"][::std::mem::size_of::() - 8usize]; + ["Alignment of TaggedPtr"][::std::mem::align_of::() - 8usize]; +}; +impl Default for TaggedPtr { + 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 TaggedPtr { + #[inline] + pub fn tag(&self) -> MyEnum { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 2u8) as u32) } + } + #[inline] + pub fn set_tag(&mut self, val: MyEnum) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 2u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_ptr(&mut self, val: ::std::os::raw::c_long) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 62u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 8usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 2u8, + { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 62u8, + { + let ptr: u64 = unsafe { ::std::mem::transmute(ptr) }; + ptr as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs b/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs new file mode 100644 index 0000000000..ac5d75735e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs @@ -0,0 +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)] +#[derive(Debug, Default, Copy, Clone)] +pub struct _bindgen_ty_1 { + 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]; +}; +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 new file mode 100644 index 0000000000..35117c74b6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs @@ -0,0 +1,262 @@ +#![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, Default, Copy, Clone)] +pub struct mach_msg_type_descriptor_t { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of mach_msg_type_descriptor_t", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of mach_msg_type_descriptor_t", + ][::std::mem::align_of::() - 4usize]; +}; +impl mach_msg_type_descriptor_t { + #[inline] + pub fn pad3(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 24u8) as u32) } + } + #[inline] + pub fn set_pad3(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 24u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_type(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 24u8, + { + let pad3: u32 = unsafe { ::std::mem::transmute(pad3) }; + pad3 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 24usize, + 8u8, + { + let type_: u32 = unsafe { ::std::mem::transmute(type_) }; + type_ as u64 + }, + ); + __bindgen_bitfield_unit + } +} 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 new file mode 100644 index 0000000000..6f9adcb5ab --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -0,0 +1,514 @@ +#![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, Default, Copy, Clone)] +pub struct Struct { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Struct"][::std::mem::size_of::() - 4usize]; + ["Alignment of Struct"][::std::mem::align_of::() - 1usize]; +}; +impl Struct { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_uchar) { + 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) -> ::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) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_c(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 6u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 16u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_e(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[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, + c: ::std::os::raw::c_uchar, + d: ::std::os::raw::c_ushort, + e: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 6u8, + { + let c: u8 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 16u8, + { + let d: u16 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 24usize, + 8u8, + { + let e: u8 = unsafe { ::std::mem::transmute(e) }; + e as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Inner { + pub _bindgen_align: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Inner"][::std::mem::size_of::() - 4usize]; + ["Alignment of Inner"][::std::mem::align_of::() - 2usize]; +}; +impl Inner { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u16) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 16u8, + { + let a: u16 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 16u8, + { + let b: u16 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Outer { + pub inner: Inner, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Outer"][::std::mem::size_of::() - 4usize]; + ["Alignment of Outer"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Outer::inner"][::std::mem::offset_of!(Outer, inner) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/block_return_type.rs b/bindgen-tests/tests/expectations/tests/block_return_type.rs new file mode 100644 index 0000000000..8ab2d70f11 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/block_return_type.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +extern crate block; +unsafe extern "C" { + pub fn func() -> _bindgen_ty_id_4; +} +pub type _bindgen_ty_id_4 = *const ::block::Block< + (::std::os::raw::c_int, ::std::os::raw::c_int), + ::std::os::raw::c_int, +>; diff --git a/bindgen-tests/tests/expectations/tests/blocklist-and-impl-debug.rs b/bindgen-tests/tests/expectations/tests/blocklist-and-impl-debug.rs new file mode 100644 index 0000000000..43e645bfc3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist-and-impl-debug.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct BlocklistMe(u8); +/// Because this type contains a blocklisted type, it should not derive Debug. +#[repr(C)] +pub struct ShouldManuallyImplDebug { + pub a: BlocklistMe, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldManuallyImplDebug", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ShouldManuallyImplDebug", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ShouldManuallyImplDebug::a", + ][::std::mem::offset_of!(ShouldManuallyImplDebug, a) - 0usize]; +}; +impl Default for ShouldManuallyImplDebug { + 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 ShouldManuallyImplDebug { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "ShouldManuallyImplDebug {{ }}") + } +} diff --git a/bindgen-tests/tests/expectations/tests/blocklist-file.rs b/bindgen-tests/tests/expectations/tests/blocklist-file.rs new file mode 100644 index 0000000000..4056ef4d2c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist-file.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct SizedIntegers { + pub x: u8, + pub y: u16, + pub z: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of SizedIntegers"][::std::mem::size_of::() - 8usize]; + ["Alignment of SizedIntegers"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: SizedIntegers::x", + ][::std::mem::offset_of!(SizedIntegers, x) - 0usize]; + [ + "Offset of field: SizedIntegers::y", + ][::std::mem::offset_of!(SizedIntegers, y) - 2usize]; + [ + "Offset of field: SizedIntegers::z", + ][::std::mem::offset_of!(SizedIntegers, z) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct StructWithBlocklistedFwdDecl { + pub b: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of StructWithBlocklistedFwdDecl", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of StructWithBlocklistedFwdDecl", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: StructWithBlocklistedFwdDecl::b", + ][::std::mem::offset_of!(StructWithBlocklistedFwdDecl, b) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/blocklist-function.rs b/bindgen-tests/tests/expectations/tests/blocklist-function.rs new file mode 100644 index 0000000000..65b66b2ac2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist-function.rs @@ -0,0 +1,28 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + } + pub mod bar { + #[allow(unused_imports)] + use self::super::super::root; + unsafe extern "C" { + #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"] + pub fn NamespacedFunction(); + } + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct C { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of C"][::std::mem::size_of::() - 1usize]; + ["Alignment of C"][::std::mem::align_of::() - 1usize]; + }; +} diff --git a/tests/expectations/tests/blocklist-item.rs b/bindgen-tests/tests/expectations/tests/blocklist-item.rs similarity index 78% rename from tests/expectations/tests/blocklist-item.rs rename to bindgen-tests/tests/expectations/tests/blocklist-item.rs index 0edee9ec32..c5daf050a1 100644 --- a/tests/expectations/tests/blocklist-item.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist-item.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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)] @@ -16,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 new file mode 100644 index 0000000000..c89cadb3d5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist-methods.rs @@ -0,0 +1,21 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo3fooEv"] + pub fn Foo_foo(this: *mut Foo) -> ::std::os::raw::c_int; +} +impl Foo { + #[inline] + pub unsafe fn foo(&mut self) -> ::std::os::raw::c_int { + Foo_foo(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/blocklist-var.rs b/bindgen-tests/tests/expectations/tests/blocklist-var.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist-var.rs @@ -0,0 +1 @@ +#![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/blocklist_bitfield_unit.rs b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs new file mode 100644 index 0000000000..77c263e3cc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs @@ -0,0 +1,118 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[path = "./struct_with_bitfields.rs"] +mod bitfields; +use bitfields::*; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct C { + pub x: ::std::os::raw::c_uchar, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub baz: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 8usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::x"][::std::mem::offset_of!(C, x) - 0usize]; + ["Offset of field: C::baz"][::std::mem::offset_of!(C, baz) - 4usize]; +}; +impl C { + #[inline] + pub fn b1(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/blocks-signature.rs b/bindgen-tests/tests/expectations/tests/blocks-signature.rs new file mode 100644 index 0000000000..93cf28e009 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocks-signature.rs @@ -0,0 +1,66 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +extern crate block; +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; +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; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] + pub fn foo(arg1: _bindgen_ty_id_50) -> bool; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] + pub fn foo_ptr(arg1: *mut _bindgen_ty_id_56) -> bool; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct contains_block_pointers { + pub val: contains_block_pointers__bindgen_ty_id_61, + pub ptr_val: *mut _bindgen_ty_id_68, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of contains_block_pointers", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of contains_block_pointers", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: contains_block_pointers::val", + ][::std::mem::offset_of!(contains_block_pointers, val) - 0usize]; + [ + "Offset of field: contains_block_pointers::ptr_val", + ][::std::mem::offset_of!(contains_block_pointers, ptr_val) - 8usize]; +}; +impl Default for contains_block_pointers { + 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 type _bindgen_ty_id_33 = *const ::block::Block<(), ()>; +pub type _bindgen_ty_id_40 = *const ::block::Block< + (dispatch_data_t, usize, *const ::std::os::raw::c_void, usize), + bool, +>; +pub type _bindgen_ty_id_50 = *const ::block::Block<(usize,), ()>; +pub type _bindgen_ty_id_56 = *const ::block::Block<(usize,), ()>; +pub type contains_block_pointers__bindgen_ty_id_61 = *const ::block::Block< + (::std::os::raw::c_int,), + (), +>; +pub type _bindgen_ty_id_68 = *const ::block::Block<(::std::os::raw::c_int,), ()>; diff --git a/bindgen-tests/tests/expectations/tests/blocks.rs b/bindgen-tests/tests/expectations/tests/blocks.rs new file mode 100644 index 0000000000..4f51113c4b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/blocks.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +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; +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; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] + pub fn foo(arg1: *mut ::std::os::raw::c_void) -> bool; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] + pub fn foo_ptr(arg1: *mut *mut ::std::os::raw::c_void) -> bool; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct contains_block_pointers { + pub val: *mut ::std::os::raw::c_void, + pub ptr_val: *mut *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of contains_block_pointers", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of contains_block_pointers", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: contains_block_pointers::val", + ][::std::mem::offset_of!(contains_block_pointers, val) - 0usize]; + [ + "Offset of field: contains_block_pointers::ptr_val", + ][::std::mem::offset_of!(contains_block_pointers, ptr_val) - 8usize]; +}; +impl Default for contains_block_pointers { + 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/bug-1529681.rs b/bindgen-tests/tests/expectations/tests/bug-1529681.rs new file mode 100644 index 0000000000..bd59c1971f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bug-1529681.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct BrowsingContext { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of BrowsingContext"][::std::mem::size_of::() - 1usize]; + ["Alignment of BrowsingContext"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/builtin-template.rs b/bindgen-tests/tests/expectations/tests/builtin-template.rs new file mode 100644 index 0000000000..53e3fbf9bf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/builtin-template.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type std_make_integer_sequence = u8; diff --git a/bindgen-tests/tests/expectations/tests/c-empty-layout.rs b/bindgen-tests/tests/expectations/tests/c-empty-layout.rs new file mode 100644 index 0000000000..709a9a59d8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/c-empty-layout.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo {} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 0usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs b/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs new file mode 100644 index 0000000000..a158565033 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C-unwind" { + pub fn foo(); +} +unsafe extern "C-unwind" { + pub fn bar(); +} +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 new file mode 100644 index 0000000000..38e63ce874 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/c_naming.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct struct_a { + pub a: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of struct_a"][::std::mem::size_of::() - 4usize]; + ["Alignment of struct_a"][::std::mem::align_of::() - 4usize]; + ["Offset of field: struct_a::a"][::std::mem::offset_of!(struct_a, a) - 0usize]; +}; +pub type a = *const struct_a; +#[repr(C)] +#[derive(Copy, Clone)] +pub union union_b { + pub a: ::std::os::raw::c_int, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of union_b"][::std::mem::size_of::() - 4usize]; + ["Alignment of union_b"][::std::mem::align_of::() - 4usize]; + ["Offset of field: union_b::a"][::std::mem::offset_of!(union_b, a) - 0usize]; + ["Offset of field: union_b::b"][::std::mem::offset_of!(union_b, b) - 0usize]; +}; +impl Default for union_b { + 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 type b = union_b; +pub const enum_c_A: enum_c = 0; +pub type enum_c = ::std::os::raw::c_uint; +unsafe extern "C" { + pub fn takes_a(arg: a); +} +unsafe extern "C" { + pub fn takes_b(arg: b); +} +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 new file mode 100644 index 0000000000..8f0502a435 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/call-conv-field.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(test))] +#[repr(C)] +#[derive(Default, Copy, Clone)] +pub struct JNINativeInterface_ { + pub GetVersion: ::std::option::Option< + unsafe extern "stdcall" fn( + env: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + pub __hack: ::std::os::raw::c_ulonglong, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of JNINativeInterface_", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of JNINativeInterface_", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: JNINativeInterface_::GetVersion", + ][::std::mem::offset_of!(JNINativeInterface_, GetVersion) - 0usize]; + [ + "Offset of field: JNINativeInterface_::__hack", + ][::std::mem::offset_of!(JNINativeInterface_, __hack) - 8usize]; +}; +unsafe extern "stdcall" { + pub fn bar(); +} diff --git a/bindgen-tests/tests/expectations/tests/call-conv-typedef.rs b/bindgen-tests/tests/expectations/tests/call-conv-typedef.rs new file mode 100644 index 0000000000..c62756f364 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/call-conv-typedef.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(test))] +pub type void_fn = ::std::option::Option; +pub type fn_ = ::std::option::Option< + unsafe extern "stdcall" fn(id: ::std::os::raw::c_int) -> void_fn, +>; diff --git a/bindgen-tests/tests/expectations/tests/canonical-types.rs b/bindgen-tests/tests/expectations/tests/canonical-types.rs new file mode 100644 index 0000000000..81d2e488a2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/canonical-types.rs @@ -0,0 +1,193 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ClassA { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ClassA_ClassAInner { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub x: *mut T, +} +impl Default for ClassA_ClassAInner { + 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, Default, Copy, Clone)] +pub struct ClassB { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ClassC { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ClassC_ClassCInnerB { + pub cache: *mut ClassC_ClassCInnerA, +} +impl Default for ClassC_ClassCInnerB { + 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 ClassC_ClassCInnerA { + pub member: *mut ClassC_ClassCInnerB, +} +impl Default for ClassC_ClassCInnerA { + 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 ClassC_ClassCInnerCRTP { + pub _address: u8, +} +impl Default for ClassC_ClassCInnerCRTP { + 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 ClassD { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ClassD"][::std::mem::size_of::() - 1usize]; + ["Alignment of ClassD"][::std::mem::align_of::() - 1usize]; +}; +impl Default for ClassD { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: ClassB_open0_ClassD_ClassCInnerCRTP_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: ClassB_open0_ClassD_ClassCInnerCRTP_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ClassCInnerCRTP { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ClassCInnerCRTP"][::std::mem::size_of::() - 1usize]; + ["Alignment of ClassCInnerCRTP"][::std::mem::align_of::() - 1usize]; +}; +impl Default for ClassCInnerCRTP { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: ClassB_open0_ClassCInnerCRTP_ClassAInner_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: ClassB_open0_ClassCInnerCRTP_ClassAInner_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ClassAInner { + pub x: *mut ClassCInnerA, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ClassAInner"][::std::mem::size_of::() - 8usize]; + ["Alignment of ClassAInner"][::std::mem::align_of::() - 8usize]; + ["Offset of field: ClassAInner::x"][::std::mem::offset_of!(ClassAInner, x) - 0usize]; +}; +impl Default for ClassAInner { + 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 ClassCInnerA { + pub member: *mut ClassCInnerB, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ClassCInnerA"][::std::mem::size_of::() - 8usize]; + ["Alignment of ClassCInnerA"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ClassCInnerA::member", + ][::std::mem::offset_of!(ClassCInnerA, member) - 0usize]; +}; +impl Default for ClassCInnerA { + 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 ClassCInnerB { + pub cache: *mut ClassCInnerA, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ClassCInnerB"][::std::mem::size_of::() - 8usize]; + ["Alignment of ClassCInnerB"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ClassCInnerB::cache", + ][::std::mem::offset_of!(ClassCInnerB, cache) - 0usize]; +}; +impl Default for ClassCInnerB { + 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/canonical_path_without_namespacing.rs b/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs new file mode 100644 index 0000000000..613da3060f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_Z3bazPN3foo3BarE"] + pub fn baz(arg1: *mut Bar); +} diff --git a/bindgen-tests/tests/expectations/tests/char.rs b/bindgen-tests/tests/expectations/tests/char.rs new file mode 100644 index 0000000000..61a81269d7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/char.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type Char = ::std::os::raw::c_char; +pub type SChar = ::std::os::raw::c_schar; +pub type UChar = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Test { + pub ch: ::std::os::raw::c_char, + pub u: ::std::os::raw::c_uchar, + pub d: ::std::os::raw::c_schar, + pub cch: ::std::os::raw::c_char, + pub cu: ::std::os::raw::c_uchar, + pub cd: ::std::os::raw::c_schar, + pub Cch: Char, + pub Cu: UChar, + pub Cd: SChar, + pub Ccch: Char, + pub Ccu: UChar, + pub Ccd: SChar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 12usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Test::ch"][::std::mem::offset_of!(Test, ch) - 0usize]; + ["Offset of field: Test::u"][::std::mem::offset_of!(Test, u) - 1usize]; + ["Offset of field: Test::d"][::std::mem::offset_of!(Test, d) - 2usize]; + ["Offset of field: Test::cch"][::std::mem::offset_of!(Test, cch) - 3usize]; + ["Offset of field: Test::cu"][::std::mem::offset_of!(Test, cu) - 4usize]; + ["Offset of field: Test::cd"][::std::mem::offset_of!(Test, cd) - 5usize]; + ["Offset of field: Test::Cch"][::std::mem::offset_of!(Test, Cch) - 6usize]; + ["Offset of field: Test::Cu"][::std::mem::offset_of!(Test, Cu) - 7usize]; + ["Offset of field: Test::Cd"][::std::mem::offset_of!(Test, Cd) - 8usize]; + ["Offset of field: Test::Ccch"][::std::mem::offset_of!(Test, Ccch) - 9usize]; + ["Offset of field: Test::Ccu"][::std::mem::offset_of!(Test, Ccu) - 10usize]; + ["Offset of field: Test::Ccd"][::std::mem::offset_of!(Test, Ccd) - 11usize]; +}; 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 new file mode 100644 index 0000000000..98ee43b374 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class.rs @@ -0,0 +1,377 @@ +#![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 const 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)] +#[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], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_zero_length_array", + ][::std::mem::size_of::() - 40usize]; + [ + "Alignment of C_with_zero_length_array", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_with_zero_length_array::a", + ][::std::mem::offset_of!(C_with_zero_length_array, a) - 0usize]; + [ + "Offset of field: C_with_zero_length_array::big_array", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_zero_length_array_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of C_with_zero_length_array_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_with_zero_length_array_2::a", + ][::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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_incomplete_array", + ][::std::mem::size_of::() - 40usize]; + [ + "Alignment of C_with_incomplete_array", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_with_incomplete_array::a", + ][::std::mem::offset_of!(C_with_incomplete_array, a) - 0usize]; + [ + "Offset of field: C_with_incomplete_array::big_array", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_incomplete_array_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of C_with_incomplete_array_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_with_incomplete_array_2::a", + ][::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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_zero_length_array_and_incomplete_array", + ][::std::mem::size_of::() - 40usize]; + [ + "Alignment of C_with_zero_length_array_and_incomplete_array", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_with_zero_length_array_and_incomplete_array::a", + ][::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", + ][::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", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C_with_zero_length_array_and_incomplete_array_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of C_with_zero_length_array_and_incomplete_array_2", + ][::std::mem::align_of::() + - 4usize]; + [ + "Offset of field: C_with_zero_length_array_and_incomplete_array_2::a", + ][::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", + ][::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, +} +#[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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of IncompleteArrayNonCopiable", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of IncompleteArrayNonCopiable", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: IncompleteArrayNonCopiable::whatever", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union Union { + pub d: f32, + pub i: ::std::os::raw::c_int, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct WithUnion { + pub data: Union, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct RealAbstractionWithTonsOfMethods { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of RealAbstractionWithTonsOfMethods", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of RealAbstractionWithTonsOfMethods", + ][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZNK32RealAbstractionWithTonsOfMethods3barEv"] + pub fn RealAbstractionWithTonsOfMethods_bar( + this: *const RealAbstractionWithTonsOfMethods, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEv"] + pub fn RealAbstractionWithTonsOfMethods_bar1( + this: *mut RealAbstractionWithTonsOfMethods, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEi"] + pub fn RealAbstractionWithTonsOfMethods_bar2( + this: *mut RealAbstractionWithTonsOfMethods, + foo: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3staEv"] + pub fn RealAbstractionWithTonsOfMethods_sta(); +} +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 new file mode 100644 index 0000000000..080f5968bc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_nested.rs @@ -0,0 +1,105 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct A { + pub member_a: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct A_B { + pub member_b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A_B"][::std::mem::size_of::() - 4usize]; + ["Alignment of A_B"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A_B::member_b"][::std::mem::offset_of!(A_B, member_b) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct A_D { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub foo: T, +} +impl Default for A_D { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 4usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::member_a"][::std::mem::offset_of!(A, member_a) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct A_C { + pub baz: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A_C"][::std::mem::size_of::() - 4usize]; + ["Alignment of A_C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A_C::baz"][::std::mem::offset_of!(A_C, baz) - 0usize]; +}; +unsafe extern "C" { + pub static mut var: A_B; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: A_D_open0_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: A_D_open0_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +unsafe extern "C" { + pub static mut baz: A_D<::std::os::raw::c_int>; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct D { + pub member: A_B, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of D"][::std::mem::size_of::() - 4usize]; + ["Alignment of D"][::std::mem::align_of::() - 4usize]; + ["Offset of field: D::member"][::std::mem::offset_of!(D, member) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Templated { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Templated_Templated_inner { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member_ptr: *mut T, +} +impl Default for Templated_Templated_inner { + 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 Templated { + 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/class_no_members.rs b/bindgen-tests/tests/expectations/tests/class_no_members.rs new file mode 100644 index 0000000000..c50da6a02d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_no_members.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct whatever { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of whatever"][::std::mem::size_of::() - 1usize]; + ["Alignment of whatever"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct whatever_child { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of whatever_child"][::std::mem::size_of::() - 1usize]; + ["Alignment of whatever_child"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct whatever_child_with_member { + pub m_member: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of whatever_child_with_member", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of whatever_child_with_member", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: whatever_child_with_member::m_member", + ][::std::mem::offset_of!(whatever_child_with_member, m_member) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/class_static.rs b/bindgen-tests/tests/expectations/tests/class_static.rs new file mode 100644 index 0000000000..d448165d62 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_static.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct MyClass { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN7MyClass7exampleE"] + pub static mut MyClass_example: *const ::std::os::raw::c_int; +} +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; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of MyClass"][::std::mem::size_of::() - 1usize]; + ["Alignment of MyClass"][::std::mem::align_of::() - 1usize]; +}; +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_static_const.rs b/bindgen-tests/tests/expectations/tests/class_static_const.rs new file mode 100644 index 0000000000..d628239c4c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_static_const.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, Hash, PartialEq, Eq)] +pub struct A { + pub _address: u8, +} +pub const A_a: ::std::os::raw::c_int = 0; +pub const A_b: i32 = 63; +pub const A_c: u32 = 255; +#[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_use_as.rs b/bindgen-tests/tests/expectations/tests/class_use_as.rs new file mode 100644 index 0000000000..ec898ff7eb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_use_as.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct whatever { + pub replacement: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of whatever"][::std::mem::size_of::() - 4usize]; + ["Alignment of whatever"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: whatever::replacement", + ][::std::mem::offset_of!(whatever, replacement) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct container { + pub c: whatever, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of container"][::std::mem::size_of::() - 4usize]; + ["Alignment of container"][::std::mem::align_of::() - 4usize]; + ["Offset of field: container::c"][::std::mem::offset_of!(container, c) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/class_with_dtor.rs b/bindgen-tests/tests/expectations/tests/class_with_dtor.rs new file mode 100644 index 0000000000..aa99f42468 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_with_dtor.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct HandleWithDtor { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: *mut T, +} +impl Default for HandleWithDtor { + 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 type HandleValue = HandleWithDtor<::std::os::raw::c_int>; +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct WithoutDtor { + pub shouldBeWithDtor: HandleValue, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithoutDtor"][::std::mem::size_of::() - 8usize]; + ["Alignment of WithoutDtor"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: WithoutDtor::shouldBeWithDtor", + ][::std::mem::offset_of!(WithoutDtor, shouldBeWithDtor) - 0usize]; +}; +impl Default for WithoutDtor { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: HandleWithDtor_open0_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: HandleWithDtor_open0_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; 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.rs b/bindgen-tests/tests/expectations/tests/class_with_inner_struct.rs new file mode 100644 index 0000000000..710026c72f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_with_inner_struct.rs @@ -0,0 +1,235 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +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, Clone, Hash, PartialEq, Eq)] +pub struct A_Segment { + pub begin: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A_Segment"][::std::mem::size_of::() - 8usize]; + ["Alignment of A_Segment"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: A_Segment::begin", + ][::std::mem::offset_of!(A_Segment, begin) - 0usize]; + ["Offset of field: A_Segment::end"][::std::mem::offset_of!(A_Segment, end) - 4usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub union A__bindgen_ty_1 { + pub f: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + ["Alignment of A__bindgen_ty_1"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: A__bindgen_ty_1::f", + ][::std::mem::offset_of!(A__bindgen_ty_1, f) - 0usize]; +}; +impl Default for A__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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union A__bindgen_ty_2 { + pub d: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A__bindgen_ty_2"][::std::mem::size_of::() - 4usize]; + ["Alignment of A__bindgen_ty_2"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: A__bindgen_ty_2::d", + ][::std::mem::offset_of!(A__bindgen_ty_2, d) - 0usize]; +}; +impl Default for A__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 12usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::c"][::std::mem::offset_of!(A, c) - 0usize]; + ["Offset of field: A::named_union"][::std::mem::offset_of!(A, named_union) - 4usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct B { + pub d: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct B_Segment { + pub begin: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B_Segment"][::std::mem::size_of::() - 8usize]; + ["Alignment of B_Segment"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: B_Segment::begin", + ][::std::mem::offset_of!(B_Segment, begin) - 0usize]; + ["Offset of field: B_Segment::end"][::std::mem::offset_of!(B_Segment, end) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 4usize]; + ["Alignment of B"][::std::mem::align_of::() - 4usize]; + ["Offset of field: B::d"][::std::mem::offset_of!(B, d) - 0usize]; +}; +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum StepSyntax { + Keyword = 0, + FunctionalWithoutKeyword = 1, + FunctionalWithStartKeyword = 2, + FunctionalWithEndKeyword = 3, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct C { + pub d: ::std::os::raw::c_uint, + pub __bindgen_anon_1: C__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union C__bindgen_ty_1 { + pub mFunc: C__bindgen_ty_1__bindgen_ty_1, + pub __bindgen_anon_1: C__bindgen_ty_1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct C__bindgen_ty_1__bindgen_ty_1 { + pub mX1: f32, + pub mY1: f32, + pub mX2: f32, + pub mY2: f32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of C__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mX1", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_1, mX1) - 0usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mY1", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_1, mY1) - 4usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mX2", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_1, mX2) - 8usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mY2", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_1, mY2) - 12usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct C__bindgen_ty_1__bindgen_ty_2 { + pub mStepSyntax: StepSyntax, + pub mSteps: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of C__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of C__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_2::mStepSyntax", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_2, mStepSyntax) - 0usize]; + [ + "Offset of field: C__bindgen_ty_1__bindgen_ty_2::mSteps", + ][::std::mem::offset_of!(C__bindgen_ty_1__bindgen_ty_2, mSteps) - 4usize]; +}; +impl Default for C__bindgen_ty_1__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C__bindgen_ty_1"][::std::mem::size_of::() - 16usize]; + ["Alignment of C__bindgen_ty_1"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C__bindgen_ty_1::mFunc", + ][::std::mem::offset_of!(C__bindgen_ty_1, mFunc) - 0usize]; +}; +impl Default for C__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() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct C_Segment { + pub begin: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C_Segment"][::std::mem::size_of::() - 8usize]; + ["Alignment of C_Segment"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: C_Segment::begin", + ][::std::mem::offset_of!(C_Segment, begin) - 0usize]; + ["Offset of field: C_Segment::end"][::std::mem::offset_of!(C_Segment, end) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 20usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::d"][::std::mem::offset_of!(C, d) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/class_with_typedef.rs b/bindgen-tests/tests/expectations/tests/class_with_typedef.rs new file mode 100644 index 0000000000..73f2b55cc3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_with_typedef.rs @@ -0,0 +1,87 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type AnotherInt = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct C { + pub c: C_MyInt, + pub ptr: *mut C_MyInt, + pub arr: [C_MyInt; 10usize], + pub d: AnotherInt, + pub other_ptr: *mut AnotherInt, +} +pub type C_MyInt = ::std::os::raw::c_int; +pub type C_Lookup = *const ::std::os::raw::c_char; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 72usize]; + ["Alignment of C"][::std::mem::align_of::() - 8usize]; + ["Offset of field: C::c"][::std::mem::offset_of!(C, c) - 0usize]; + ["Offset of field: C::ptr"][::std::mem::offset_of!(C, ptr) - 8usize]; + ["Offset of field: C::arr"][::std::mem::offset_of!(C, arr) - 16usize]; + ["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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1C6methodEi"] + pub fn C_method(this: *mut C, c: C_MyInt); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1C9methodRefERi"] + pub fn C_methodRef(this: *mut C, c: *mut C_MyInt); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1C16complexMethodRefERPKc"] + pub fn C_complexMethodRef(this: *mut C, c: *mut C_Lookup); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1C13anotherMethodEi"] + pub fn C_anotherMethod(this: *mut C, c: AnotherInt); +} +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 unsafe fn method(&mut self, c: C_MyInt) { + C_method(self, c) + } + #[inline] + pub unsafe fn methodRef(&mut self, c: *mut C_MyInt) { + C_methodRef(self, c) + } + #[inline] + pub unsafe fn complexMethodRef(&mut self, c: *mut C_Lookup) { + C_complexMethodRef(self, c) + } + #[inline] + pub unsafe fn anotherMethod(&mut self, c: AnotherInt) { + C_anotherMethod(self, c) + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct D { + pub _base: C, + pub ptr: *mut C_MyInt, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of D"][::std::mem::size_of::() - 80usize]; + ["Alignment of D"][::std::mem::align_of::() - 8usize]; + ["Offset of field: D::ptr"][::std::mem::offset_of!(D, ptr) - 72usize]; +}; +impl Default for D { + 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/comment-indent.rs b/bindgen-tests/tests/expectations/tests/comment-indent.rs new file mode 100644 index 0000000000..72b167d00c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/comment-indent.rs @@ -0,0 +1,81 @@ +#![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; + /** This is a multi-line doc comment. + + This class is really really interesting, look!*/ + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Foo { + pub _address: u8, + } + /** This nested class is also a multi-line doc comment. + + This class is not so interesting, but worth a bit of docs too!*/ + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Foo_Bar { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Foo_Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo_Bar"][::std::mem::align_of::() - 1usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; + }; + pub mod test { + #[allow(unused_imports)] + use self::super::super::root; + /** I'm in a namespace, and thus I may be on a rust module, most of the time. + My documentation is pretty extensive, I guess.*/ + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Baz { + /** This member is plain awesome, just amazing. + + It also has super-extensive docs, with even a nice ascii-art diagram. + + +------+ +-------+ + | foo | ----> | bar | + +------+ +-------+*/ + pub member: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Baz::member", + ][::std::mem::offset_of!(Baz, member) - 0usize]; + }; + /** I'm in an inline namespace, and as such I shouldn't get generated inside + a rust module, except when the relevant option is specified. Also, this + comment shouldn't be misaligned.*/ + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct InInlineNS { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of InInlineNS"][::std::mem::size_of::() - 1usize]; + ["Alignment of InInlineNS"][::std::mem::align_of::() - 1usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bazz { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Bazz"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bazz"][::std::mem::align_of::() - 1usize]; + }; + } +} diff --git a/bindgen-tests/tests/expectations/tests/complex.rs b/bindgen-tests/tests/expectations/tests/complex.rs new file mode 100644 index 0000000000..233b86ea36 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/complex.rs @@ -0,0 +1,77 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] +#[repr(C)] +pub struct __BindgenComplex { + pub re: T, + pub im: T, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct TestDouble { + pub mMember: __BindgenComplex, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestDouble"][::std::mem::size_of::() - 16usize]; + ["Alignment of TestDouble"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: TestDouble::mMember", + ][::std::mem::offset_of!(TestDouble, mMember) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct TestDoublePtr { + pub mMember: *mut __BindgenComplex, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestDoublePtr"][::std::mem::size_of::() - 8usize]; + ["Alignment of TestDoublePtr"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: TestDoublePtr::mMember", + ][::std::mem::offset_of!(TestDoublePtr, mMember) - 0usize]; +}; +impl Default for TestDoublePtr { + 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, Default, Copy, Clone, PartialEq)] +pub struct TestFloat { + pub mMember: __BindgenComplex, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestFloat"][::std::mem::size_of::() - 8usize]; + ["Alignment of TestFloat"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: TestFloat::mMember", + ][::std::mem::offset_of!(TestFloat, mMember) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct TestFloatPtr { + pub mMember: *mut __BindgenComplex, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestFloatPtr"][::std::mem::size_of::() - 8usize]; + ["Alignment of TestFloatPtr"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: TestFloatPtr::mMember", + ][::std::mem::offset_of!(TestFloatPtr, mMember) - 0usize]; +}; +impl Default for TestFloatPtr { + 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/complex_global.rs b/bindgen-tests/tests/expectations/tests/complex_global.rs new file mode 100644 index 0000000000..c818df676e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/complex_global.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] +#[repr(C)] +pub struct __BindgenComplex { + pub re: T, + pub im: T, +} +unsafe extern "C" { + pub static mut globalValueFloat: __BindgenComplex; +} +unsafe extern "C" { + pub static mut globalValueDouble: __BindgenComplex; +} +unsafe extern "C" { + pub static mut globalValueLongDouble: __BindgenComplex; +} diff --git a/bindgen-tests/tests/expectations/tests/const-const-mut-ptr.rs b/bindgen-tests/tests/expectations/tests/const-const-mut-ptr.rs new file mode 100644 index 0000000000..72a34da105 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const-const-mut-ptr.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub bar: *const *const *mut *const ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/const_array.rs b/bindgen-tests/tests/expectations/tests/const_array.rs new file mode 100644 index 0000000000..30852deb36 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_array.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub static foo: [::std::os::raw::c_int; 1usize]; +} +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 new file mode 100644 index 0000000000..fb26311115 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_array_fn_arg.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..034856d359 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_array_typedef.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct strct { + pub field: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of strct"][::std::mem::size_of::() - 4usize]; + ["Alignment of strct"][::std::mem::align_of::() - 4usize]; + ["Offset of field: strct::field"][::std::mem::offset_of!(strct, field) - 0usize]; +}; +pub type typ = [strct; 1usize]; +unsafe extern "C" { + pub static mut w: typ; +} +unsafe extern "C" { + pub static mut x: *mut strct; +} +unsafe extern "C" { + pub static y: typ; +} +unsafe extern "C" { + pub static mut z: *const strct; +} +unsafe extern "C" { + pub fn function(a: *const strct, b: *const strct); +} diff --git a/bindgen-tests/tests/expectations/tests/const_bool.rs b/bindgen-tests/tests/expectations/tests/const_bool.rs new file mode 100644 index 0000000000..2cbab47390 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_bool.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const k: bool = true; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub _address: u8, +} +pub const A_k: bool = false; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 1usize]; + ["Alignment of A"][::std::mem::align_of::() - 1usize]; +}; +pub type foo = bool; +pub const k2: foo = true; diff --git a/bindgen-tests/tests/expectations/tests/const_enum_unnamed.rs b/bindgen-tests/tests/expectations/tests/const_enum_unnamed.rs new file mode 100644 index 0000000000..f49d825224 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_enum_unnamed.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO_BAR: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAR; +pub const FOO_BAZ: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAZ; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + FOO_BAR = 0, + FOO_BAZ = 1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +pub const Foo_FOO_BAR: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::FOO_BAR; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo__bindgen_ty_1 { + FOO_BAR = 10, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; 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 new file mode 100644 index 0000000000..db0ce114fb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_multidim_array_fn_arg.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..9b9e38c1e7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_ptr.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..ed49b69f64 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/const_resolved_ty.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(foo: *const u8); +} diff --git a/tests/expectations/tests/const_tparam.rs b/bindgen-tests/tests/expectations/tests/const_tparam.rs similarity index 80% rename from tests/expectations/tests/const_tparam.rs rename to bindgen-tests/tests/expectations/tests/const_tparam.rs index ec256872df..c6b16a8959 100644 --- a/tests/expectations/tests/const_tparam.rs +++ b/bindgen-tests/tests/expectations/tests/const_tparam.rs @@ -1,16 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct C { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub foo: *const T, pub bar: *const T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for C { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/constant-evaluate.rs b/bindgen-tests/tests/expectations/tests/constant-evaluate.rs new file mode 100644 index 0000000000..bbcf6d5450 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constant-evaluate.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; +pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + foo = 4, + bar = 8, +} +pub type EasyToOverflow = ::std::os::raw::c_ulonglong; +pub const k: EasyToOverflow = 2147483648; +pub const k_expr: EasyToOverflow = 1152921504606846976; +pub const wow: EasyToOverflow = 2147483648; +pub const BAZ: ::std::os::raw::c_longlong = 24; +pub const fuzz: f64 = 51.0; +pub const BAZZ: ::std::os::raw::c_char = 53; +pub const WAT: ::std::os::raw::c_char = 0; +pub const bytestring: &[u8; 4] = b"Foo\0"; +pub const NOT_UTF8: &[u8; 5] = b"\xF0(\x8C(\0"; diff --git a/bindgen-tests/tests/expectations/tests/constant-non-specialized-tp.rs b/bindgen-tests/tests/expectations/tests/constant-non-specialized-tp.rs new file mode 100644 index 0000000000..968ec350aa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constant-non-specialized-tp.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Outer { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Outer_Inner { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/constified-enum-module-overflow.rs b/bindgen-tests/tests/expectations/tests/constified-enum-module-overflow.rs new file mode 100644 index 0000000000..e5eada9abc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constified-enum-module-overflow.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct C { + pub _address: u8, +} +pub type C_U = B; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub u: B, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 1usize]; + ["Alignment of A"][::std::mem::align_of::() - 1usize]; + ["Offset of field: A::u"][::std::mem::offset_of!(A, u) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: C_open0_A_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: C_open0_A_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_A_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: B_open0_A_close0", + ][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/constify-all-enums.rs b/bindgen-tests/tests/expectations/tests/constify-all-enums.rs new file mode 100644 index 0000000000..7913454b56 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-all-enums.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const foo_THIS: foo = 0; +pub const foo_SHOULD_BE: foo = 1; +pub const foo_A_CONSTANT: foo = 2; +pub type foo = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bar { + pub this_should_work: foo, +} +#[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::this_should_work", + ][::std::mem::offset_of!(bar, this_should_work) - 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/constify-enum.rs b/bindgen-tests/tests/expectations/tests/constify-enum.rs new file mode 100644 index 0000000000..67d2749c51 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-enum.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue: nsCSSPropertyID = nsCSSPropertyID::eCSSProperty_COUNT_unexistingVariantValue; +impl nsCSSPropertyID { + pub const eCSSProperty_COUNT: nsCSSPropertyID = nsCSSPropertyID::eCSSPropertyAlias_aa; +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum nsCSSPropertyID { + eCSSProperty_a = 0, + eCSSProperty_b = 1, + eCSSPropertyAlias_aa = 2, + eCSSPropertyAlias_bb = 3, + ///<
+ eCSSProperty_COUNT_unexistingVariantValue = 4, +} diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs new file mode 100644 index 0000000000..aad696d074 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs @@ -0,0 +1,47 @@ +#![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; + pub const A_CONSTANT: Type = 2; +} +pub use self::foo::Type as foo_alias1; +pub use self::foo_alias1 as foo_alias2; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bar { + pub this_should_work: foo::Type, +} +#[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::this_should_work", + ][::std::mem::offset_of!(bar, this_should_work) - 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() + } + } +} +unsafe extern "C" { + pub fn func1( + arg1: foo::Type, + arg2: *mut foo::Type, + arg3: *mut *mut foo::Type, + ) -> *mut foo::Type; +} +unsafe extern "C" { + pub fn func2( + arg1: foo_alias1, + arg2: *mut foo_alias1, + arg3: *mut *mut foo_alias1, + ) -> *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 new file mode 100644 index 0000000000..cdf6e7ebb4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-namespace.rs @@ -0,0 +1,48 @@ +#![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 ns1 { + #[allow(unused_imports)] + use self::super::super::root; + pub mod ns2 { + #[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; + pub const A_CONSTANT: Type = 2; + } + } + pub mod ns3 { + #[allow(unused_imports)] + use self::super::super::super::root; + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct bar { + pub this_should_work: root::ns1::ns2::foo::Type, + } + #[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::this_should_work", + ][::std::mem::offset_of!(bar, this_should_work) - 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/constify-module-enums-shadow-name.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs new file mode 100644 index 0000000000..987f4463a2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs @@ -0,0 +1,30 @@ +#![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; + pub const Type1: Type = 2; + pub const Type__: Type = 3; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bar { + pub member: foo::Type, +} +#[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::member"][::std::mem::offset_of!(bar, member) - 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/constify-module-enums-simple-alias.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs new file mode 100644 index 0000000000..5f7b9ede4a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs @@ -0,0 +1,46 @@ +#![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; + pub const Variant3: Type = 2; +} +pub use self::Foo::Type as Foo_alias1; +pub use self::Foo_alias1 as Foo_alias2; +pub use self::Foo_alias2 as Foo_alias3; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Bar { + pub baz1: Foo::Type, + pub baz2: Foo_alias1, + pub baz3: Foo_alias2, + pub baz4: Foo_alias3, + pub baz_ptr1: *mut Foo::Type, + pub baz_ptr2: *mut Foo_alias1, + pub baz_ptr3: *mut Foo_alias2, + pub baz_ptr4: *mut Foo_alias3, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 48usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::baz1"][::std::mem::offset_of!(Bar, baz1) - 0usize]; + ["Offset of field: Bar::baz2"][::std::mem::offset_of!(Bar, baz2) - 4usize]; + ["Offset of field: Bar::baz3"][::std::mem::offset_of!(Bar, baz3) - 8usize]; + ["Offset of field: Bar::baz4"][::std::mem::offset_of!(Bar, baz4) - 12usize]; + ["Offset of field: Bar::baz_ptr1"][::std::mem::offset_of!(Bar, baz_ptr1) - 16usize]; + ["Offset of field: Bar::baz_ptr2"][::std::mem::offset_of!(Bar, baz_ptr2) - 24usize]; + ["Offset of field: Bar::baz_ptr3"][::std::mem::offset_of!(Bar, baz_ptr3) - 32usize]; + ["Offset of field: Bar::baz_ptr4"][::std::mem::offset_of!(Bar, baz_ptr4) - 40usize]; +}; +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/constify-module-enums-simple-nonamespace.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs new file mode 100644 index 0000000000..dc59f5fc1d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs @@ -0,0 +1,30 @@ +#![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; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Bar { + pub baz1: one_Foo::Type, + pub baz2: *mut one_Foo::Type, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 16usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::baz1"][::std::mem::offset_of!(Bar, baz1) - 0usize]; + ["Offset of field: Bar::baz2"][::std::mem::offset_of!(Bar, baz2) - 8usize]; +}; +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/constify-module-enums-types.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs new file mode 100644 index 0000000000..a4a69fd72d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs @@ -0,0 +1,173 @@ +#![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; + pub const A_CONSTANT: Type = 2; + pub const ALSO_THIS: Type = 42; + 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; + pub const A_CONSTANT: Type = 2; + 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; +} +pub use self::foo::Type as foo_alias1; +pub use self::foo_alias1 as foo_alias2; +pub use self::foo_alias2 as foo_alias3; +pub use self::anon_enum::Type as anon_enum_alias1; +pub use self::anon_enum_alias1 as anon_enum_alias2; +pub use self::anon_enum_alias2 as anon_enum_alias3; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bar { + pub member1: foo::Type, + pub member2: foo_alias1, + pub member3: foo_alias2, + pub member4: foo_alias3, + pub member5: ns1_foo::Type, + pub member6: *mut ns2_Foo::Type, + pub member7: anon_enum::Type, + pub member8: anon_enum_alias1, + pub member9: anon_enum_alias2, + pub member10: anon_enum_alias3, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar"][::std::mem::size_of::() - 48usize]; + ["Alignment of bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: bar::member1"][::std::mem::offset_of!(bar, member1) - 0usize]; + ["Offset of field: bar::member2"][::std::mem::offset_of!(bar, member2) - 4usize]; + ["Offset of field: bar::member3"][::std::mem::offset_of!(bar, member3) - 8usize]; + ["Offset of field: bar::member4"][::std::mem::offset_of!(bar, member4) - 12usize]; + ["Offset of field: bar::member5"][::std::mem::offset_of!(bar, member5) - 16usize]; + ["Offset of field: bar::member6"][::std::mem::offset_of!(bar, member6) - 24usize]; + ["Offset of field: bar::member7"][::std::mem::offset_of!(bar, member7) - 32usize]; + ["Offset of field: bar::member8"][::std::mem::offset_of!(bar, member8) - 36usize]; + ["Offset of field: bar::member9"][::std::mem::offset_of!(bar, member9) - 40usize]; + ["Offset of field: bar::member10"][::std::mem::offset_of!(bar, member10) - 44usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Baz { + pub member1: ns2_Foo::Type, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Baz::member1"][::std::mem::offset_of!(Baz, member1) - 0usize]; +}; +impl Default for Baz { + 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 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; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Bar { + pub baz: *mut one_Foo::Type, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::baz"][::std::mem::offset_of!(Bar, baz) - 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() + } + } +} +unsafe extern "C" { + #[link_name = "\u{1}_Z5func13fooPS_PS0_"] + pub fn func1( + arg1: foo::Type, + arg2: *mut foo::Type, + arg3: *mut *mut foo::Type, + ) -> *mut foo::Type; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z5func23fooPS_PS0_"] + pub fn func2( + arg1: foo_alias1, + arg2: *mut foo_alias1, + arg3: *mut *mut foo_alias1, + ) -> *mut foo_alias1; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Thing { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub thing: T, +} +impl Default for Thing { + 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}_Z5func35ThingI3fooE"] + pub fn func3(arg1: Thing) -> foo::Type; +} +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 new file mode 100644 index 0000000000..2585311d29 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constructor-tp.rs @@ -0,0 +1,28 @@ +#![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, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3BarC1Ev"] + pub fn Bar_Bar(this: *mut Bar); +} +impl Bar { + #[inline] + pub unsafe fn new() -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + Bar_Bar(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() + } +} diff --git a/bindgen-tests/tests/expectations/tests/constructors.rs b/bindgen-tests/tests/expectations/tests/constructors.rs new file mode 100644 index 0000000000..45c29e61e5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constructors.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TestOverload { + pub _address: u8, +} +#[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" { + #[link_name = "\u{1}_ZN12TestOverloadC1Ei"] + pub fn TestOverload_TestOverload( + this: *mut TestOverload, + arg1: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN12TestOverloadC1Ed"] + pub fn TestOverload_TestOverload1(this: *mut TestOverload, arg1: f64); +} +impl TestOverload { + #[inline] + pub unsafe fn new(arg1: ::std::os::raw::c_int) -> Self { + 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::MaybeUninit::uninit(); + TestOverload_TestOverload1(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TestPublicNoArgs { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestPublicNoArgs"][::std::mem::size_of::() - 1usize]; + [ + "Alignment of TestPublicNoArgs", + ][::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::MaybeUninit::uninit(); + TestPublicNoArgs_TestPublicNoArgs(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() + } +} diff --git a/bindgen-tests/tests/expectations/tests/constructors_1_33.rs b/bindgen-tests/tests/expectations/tests/constructors_1_33.rs new file mode 100644 index 0000000000..5dbda00007 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/constructors_1_33.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TestOverload { + pub _address: u8, +} +#[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( + this: *mut TestOverload, + arg1: ::std::os::raw::c_int, + ); +} +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); +} +impl TestOverload { + #[inline] + pub unsafe fn new(arg1: ::std::os::raw::c_int) -> Self { + 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::MaybeUninit::uninit(); + TestOverload_TestOverload1(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TestPublicNoArgs { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestPublicNoArgs"][::std::mem::size_of::() - 1usize]; + [ + "Alignment of TestPublicNoArgs", + ][::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::MaybeUninit::uninit(); + TestPublicNoArgs_TestPublicNoArgs(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() + } +} diff --git a/bindgen-tests/tests/expectations/tests/contains-vs-inherits-zero-sized.rs b/bindgen-tests/tests/expectations/tests/contains-vs-inherits-zero-sized.rs new file mode 100644 index 0000000000..3362280843 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/contains-vs-inherits-zero-sized.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// This should get an `_address` byte. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Empty { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Empty"][::std::mem::size_of::() - 1usize]; + ["Alignment of Empty"][::std::mem::align_of::() - 1usize]; +}; +/** This should not get an `_address` byte, so `sizeof(Inherits)` should be + `1`.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Inherits { + pub b: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Inherits"][::std::mem::size_of::() - 1usize]; + ["Alignment of Inherits"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Inherits::b"][::std::mem::offset_of!(Inherits, b) - 0usize]; +}; +/** This should not get an `_address` byte, but contains `Empty` which *does* get + one, so `sizeof(Contains)` should be `1 + 1`.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Contains { + pub empty: Empty, + pub b: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Contains"][::std::mem::size_of::() - 2usize]; + ["Alignment of Contains"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: Contains::empty", + ][::std::mem::offset_of!(Contains, empty) - 0usize]; + ["Offset of field: Contains::b"][::std::mem::offset_of!(Contains, b) - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/convert-cpp-comment-to-rust.rs b/bindgen-tests/tests/expectations/tests/convert-cpp-comment-to-rust.rs new file mode 100644 index 0000000000..96f9e6fd2a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/convert-cpp-comment-to-rust.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type mbedtls_mpi_uint = ::std::os::raw::c_uint; +/// \brief MPI structure +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mbedtls_mpi { + ///< integer sign + pub s: ::std::os::raw::c_int, + ///< total # of limbs + pub n: ::std::os::raw::c_ulong, + ///< pointer to limbs + pub p: *mut mbedtls_mpi_uint, +} +impl Default for mbedtls_mpi { + 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/convert-floats.rs b/bindgen-tests/tests/expectations/tests/convert-floats.rs new file mode 100644 index 0000000000..9ca939f7c5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/convert-floats.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] +#[repr(C)] +pub struct __BindgenComplex { + pub re: T, + pub im: T, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub bar: ::std::os::raw::c_float, + pub baz: ::std::os::raw::c_float, + pub bazz: ::std::os::raw::c_double, + pub bazzz: *mut u128, + pub complexFloat: __BindgenComplex<::std::os::raw::c_float>, + pub complexDouble: __BindgenComplex<::std::os::raw::c_double>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 48usize]; + ["Alignment of foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; + ["Offset of field: foo::baz"][::std::mem::offset_of!(foo, baz) - 4usize]; + ["Offset of field: foo::bazz"][::std::mem::offset_of!(foo, bazz) - 8usize]; + ["Offset of field: foo::bazzz"][::std::mem::offset_of!(foo, bazzz) - 16usize]; + [ + "Offset of field: foo::complexFloat", + ][::std::mem::offset_of!(foo, complexFloat) - 24usize]; + [ + "Offset of field: foo::complexDouble", + ][::std::mem::offset_of!(foo, complexDouble) - 32usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/core_ffi_c.rs b/bindgen-tests/tests/expectations/tests/core_ffi_c.rs new file mode 100644 index 0000000000..42c9272034 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/core_ffi_c.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type c_char = ::core::ffi::c_char; +pub type c_double = ::core::ffi::c_double; +pub type c_float = ::core::ffi::c_float; +pub type c_int = ::core::ffi::c_int; +pub type c_long = ::core::ffi::c_long; +pub type c_longlong = ::core::ffi::c_longlong; +pub type c_schar = ::core::ffi::c_schar; +pub type c_short = ::core::ffi::c_short; +pub type c_uchar = ::core::ffi::c_uchar; +pub type c_uint = ::core::ffi::c_uint; +pub type c_ulong = ::core::ffi::c_ulong; +pub type c_ulonglong = ::core::ffi::c_ulonglong; +pub type c_ushort = ::core::ffi::c_ushort; diff --git a/bindgen-tests/tests/expectations/tests/cpp-empty-layout.rs b/bindgen-tests/tests/expectations/tests/cpp-empty-layout.rs new file mode 100644 index 0000000000..551dff82cf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/cpp-empty-layout.rs @@ -0,0 +1,11 @@ +#![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]; +}; diff --git a/bindgen-tests/tests/expectations/tests/crtp.rs b/bindgen-tests/tests/expectations/tests/crtp.rs new file mode 100644 index 0000000000..68397041b7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/crtp.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Base { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Derived { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Derived"][::std::mem::size_of::() - 1usize]; + ["Alignment of Derived"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct BaseWithDestructor { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default)] +pub struct DerivedFromBaseWithDestructor { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of DerivedFromBaseWithDestructor", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of DerivedFromBaseWithDestructor", + ][::std::mem::align_of::() - 1usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Base_open0_Derived_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: Base_open0_Derived_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: BaseWithDestructor_open0_DerivedFromBaseWithDestructor_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: BaseWithDestructor_open0_DerivedFromBaseWithDestructor_close0", + ][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/ctypes-prefix-path.rs b/bindgen-tests/tests/expectations/tests/ctypes-prefix-path.rs new file mode 100644 index 0000000000..5f947f9cea --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/ctypes-prefix-path.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![no_std] +mod libc { + pub mod foo { + pub type c_int = i32; + pub enum c_void {} + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub a: libc::foo::c_int, + pub b: libc::foo::c_int, + pub bar: *mut libc::foo::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::core::mem::size_of::() - 16usize]; + ["Alignment of foo"][::core::mem::align_of::() - 8usize]; + ["Offset of field: foo::a"][::core::mem::offset_of!(foo, a) - 0usize]; + ["Offset of field: foo::b"][::core::mem::offset_of!(foo, b) - 4usize]; + ["Offset of field: foo::bar"][::core::mem::offset_of!(foo, bar) - 8usize]; +}; +impl Default for foo { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/dash_language.rs b/bindgen-tests/tests/expectations/tests/dash_language.rs new file mode 100644 index 0000000000..f405a35604 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dash_language.rs @@ -0,0 +1,6 @@ +#![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 bar: ::std::os::raw::c_int, +} diff --git a/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs b/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs new file mode 100644 index 0000000000..122d41a12d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..a559d33b4a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/decl_ptr_to_array.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..2a75aa8d86 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/default-enum-style-constified-module.rs @@ -0,0 +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; +} +unsafe extern "C" { + pub fn func(x: Foo::Type); +} diff --git a/tests/expectations/tests/default-macro-constant-type-signed.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs similarity index 92% rename from tests/expectations/tests/default-macro-constant-type-signed.rs rename to bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs index 38ebc531b3..7fca57b6b9 100644 --- a/tests/expectations/tests/default-macro-constant-type-signed.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const N0: i32 = 0; pub const N1: i32 = 1; pub const N2: i32 = 2; @@ -36,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, @@ -46,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/tests/expectations/tests/default-macro-constant-type-unsigned.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs similarity index 92% rename from tests/expectations/tests/default-macro-constant-type-unsigned.rs rename to bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs index 5571563bcd..d34d050a1a 100644 --- a/tests/expectations/tests/default-macro-constant-type-unsigned.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const N0: u32 = 0; pub const N1: u32 = 1; pub const N2: u32 = 2; @@ -36,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, @@ -46,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/tests/expectations/tests/default-macro-constant-type.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs similarity index 92% rename from tests/expectations/tests/default-macro-constant-type.rs rename to bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs index 5571563bcd..d34d050a1a 100644 --- a/tests/expectations/tests/default-macro-constant-type.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const N0: u32 = 0; pub const N1: u32 = 1; pub const N2: u32 = 2; @@ -36,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, @@ -46,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 new file mode 100644 index 0000000000..67f8a486de --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/default-template-parameter.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, + pub u: U, +} +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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Foo_open0_bool__int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: Foo_open0_bool__int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +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 new file mode 100644 index 0000000000..aeefb2e0f9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs @@ -0,0 +1,301 @@ +#![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, Default, Copy, Clone)] +pub struct Point { + pub(crate) x: ::std::os::raw::c_int, + pub(crate) y: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Color { + pub(crate) _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl Color { + #[inline] + pub(crate) fn r(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub(crate) fn set_r(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub(crate) fn set_g(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub(crate) fn set_b(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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, + b: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let r: u8 = unsafe { ::std::mem::transmute(r) }; + r as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let g: u8 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_private.rs b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs new file mode 100644 index 0000000000..dceed75e36 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs @@ -0,0 +1,301 @@ +#![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, Default, Copy, Clone)] +pub struct Point { + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Color { + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl Color { + #[inline] + fn r(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + fn set_r(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_g(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_b(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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, + b: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let r: u8 = unsafe { ::std::mem::transmute(r) }; + r as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let g: u8 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} 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 new file mode 100644 index 0000000000..f43be84bb0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs @@ -0,0 +1,301 @@ +#![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, Default, Copy, Clone)] +pub struct Point { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Color { + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl Color { + #[inline] + pub fn r(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_r(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_g(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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, + b: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let r: u8 = unsafe { ::std::mem::transmute(r) }; + r as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let g: u8 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/deleted-function.rs b/bindgen-tests/tests/expectations/tests/deleted-function.rs new file mode 100644 index 0000000000..fc8588121f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/deleted-function.rs @@ -0,0 +1,61 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1A17inline_definitionEv"] + pub fn A_inline_definition(this: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1A22out_of_line_definitionEv"] + pub fn A_out_of_line_definition(this: *mut A); +} +impl A { + #[inline] + pub unsafe fn inline_definition(&mut self) { + A_inline_definition(self) + } + #[inline] + pub unsafe fn out_of_line_definition(&mut self) { + A_out_of_line_definition(self) + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 1usize]; + ["Alignment of B"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct C { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 1usize]; + ["Alignment of C"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1CC1ERS_"] + pub fn C_C(this: *mut C, arg1: *mut C); +} +impl C { + #[inline] + pub unsafe fn new(arg1: *mut C) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + C_C(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } +} 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 new file mode 100644 index 0000000000..7fa8bc41ab --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs @@ -0,0 +1,256 @@ +#![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) }; + } + } +} +/** 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(Debug, Copy, Clone, PartialEq)] +pub struct Foo { + pub large: [::std::os::raw::c_int; 33usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub __bindgen_padding_0: u16, +} +#[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; +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo9set_type_Ec"] + pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo8set_typeEc"] + pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); +} +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 type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) } + } + #[inline] + pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[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]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let type__bindgen_bitfield: u8 = unsafe { + ::std::mem::transmute(type__bindgen_bitfield) + }; + type__bindgen_bitfield as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { + Foo_type(self) + } + #[inline] + pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type_(self, c) + } + #[inline] + pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_char) { + Foo_set_type(self, c) + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-clone.rs b/bindgen-tests/tests/expectations/tests/derive-clone.rs new file mode 100644 index 0000000000..ccbdf5bd70 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-clone.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// This struct should derive `Clone`. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ShouldDeriveClone { + pub large: [::std::os::raw::c_int; 33usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ShouldDeriveClone"][::std::mem::size_of::() - 132usize]; + [ + "Alignment of ShouldDeriveClone", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-custom-cli.rs b/bindgen-tests/tests/expectations/tests/derive-custom-cli.rs new file mode 100644 index 0000000000..59a3a76571 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-custom-cli.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Clone, Default)] +pub struct foo_struct { + pub inner: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo_struct"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo_struct"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo_struct::inner", + ][::std::mem::offset_of!(foo_struct, inner) - 0usize]; +}; +#[repr(u32)] +#[derive(Clone, Hash, PartialEq, Eq, Copy)] +pub enum foo_enum { + inner = 0, +} +#[repr(C)] +#[derive(Clone, Copy)] +pub union foo_union { + pub fst: ::std::mem::ManuallyDrop<::std::os::raw::c_int>, + pub snd: ::std::mem::ManuallyDrop, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo_union"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo_union"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo_union::fst"][::std::mem::offset_of!(foo_union, fst) - 0usize]; + ["Offset of field: foo_union::snd"][::std::mem::offset_of!(foo_union, snd) - 0usize]; +}; +#[repr(C)] +pub struct non_matching { + pub inner: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of non_matching"][::std::mem::size_of::() - 4usize]; + ["Alignment of non_matching"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: non_matching::inner", + ][::std::mem::offset_of!(non_matching, inner) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-custom.rs b/bindgen-tests/tests/expectations/tests/derive-custom.rs new file mode 100644 index 0000000000..9a69ebbb73 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-custom.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Default, Debug)] +pub struct my_type { + pub a: ::std::os::raw::c_int, +} +/**
+
*/ +#[repr(C)] +#[derive(Default, Debug, Clone)] +pub struct my_type2 { + pub a: ::std::os::raw::c_uint, +} +///
+#[repr(C)] +#[derive(Default, Debug, Clone)] +pub struct my_type3 { + pub a: ::std::os::raw::c_ulong, +} 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 new file mode 100644 index 0000000000..937ad4ad0c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs @@ -0,0 +1,268 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +extern crate core; +#[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: [::core::ffi::c_int; 50usize], +} +#[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(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl C { + #[inline] + pub fn a(&self) -> bool { + unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_a(&mut self, val: bool) { + unsafe { + let val: u8 = ::core::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b(&mut self, val: bool) { + unsafe { + let val: u8 = ::core::mem::transmute(val); + self._bitfield_1.set(1usize, 7u8, val as u64) + } + } + #[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 + .set( + 0usize, + 1u8, + { + let a: u8 = unsafe { ::core::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 7u8, + { + let b: u8 = unsafe { ::core::mem::transmute(b) }; + b as u64 + }, + ); + __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 new file mode 100644 index 0000000000..87cbb7346c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.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-function-pointer.rs b/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs new file mode 100644 index 0000000000..eaaa8ef9d4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Nice { + pub pointer: Nice_Function, + pub large_array: [::std::os::raw::c_int; 34usize], +} +pub type Nice_Function = ::std::option::Option< + unsafe extern "C" fn(data: ::std::os::raw::c_int), +>; +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs b/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs new file mode 100644 index 0000000000..86e530463f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs @@ -0,0 +1,16 @@ +#![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], +} +impl Default for Generic { + 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/derive-debug-mangle-name.rs b/bindgen-tests/tests/expectations/tests/derive-debug-mangle-name.rs new file mode 100644 index 0000000000..34b4a87d65 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-mangle-name.rs @@ -0,0 +1,74 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct perf_event_attr { + pub type_: ::std::os::raw::c_uint, + pub a: f32, + pub __bindgen_anon_1: perf_event_attr__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union perf_event_attr__bindgen_ty_1 { + pub b: ::std::os::raw::c_int, + pub c: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of perf_event_attr__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of perf_event_attr__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: perf_event_attr__bindgen_ty_1::b", + ][::std::mem::offset_of!(perf_event_attr__bindgen_ty_1, b) - 0usize]; + [ + "Offset of field: perf_event_attr__bindgen_ty_1::c", + ][::std::mem::offset_of!(perf_event_attr__bindgen_ty_1, c) - 0usize]; +}; +impl Default for perf_event_attr__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 ::std::fmt::Debug for perf_event_attr__bindgen_ty_1 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "perf_event_attr__bindgen_ty_1 {{ union }}") + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of perf_event_attr"][::std::mem::size_of::() - 12usize]; + ["Alignment of perf_event_attr"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: perf_event_attr::type_", + ][::std::mem::offset_of!(perf_event_attr, type_) - 0usize]; + [ + "Offset of field: perf_event_attr::a", + ][::std::mem::offset_of!(perf_event_attr, a) - 4usize]; +}; +impl Default for perf_event_attr { + 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 perf_event_attr { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!( + f, + "perf_event_attr {{ type: {:?}, a: {:?}, __bindgen_anon_1: {:?} }}", + self.type_, + self.a, + self.__bindgen_anon_1, + ) + } +} 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 new file mode 100644 index 0000000000..9d75e74d77 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs @@ -0,0 +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 __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} +#[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 new file mode 100644 index 0000000000..4ec1fb2a35 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-opaque.rs @@ -0,0 +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)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} +#[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, +} +#[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", + ][::std::mem::offset_of!(OpaqueUser, opaque) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-default-and-blocklist.rs b/bindgen-tests/tests/expectations/tests/derive-default-and-blocklist.rs new file mode 100644 index 0000000000..6ce99e5093 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-default-and-blocklist.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct BlocklistMe(u8); +/** Because this type contains a blocklisted type, it should not derive + Default. Instead, we should emit a `mem::zeroed` implementation.*/ +#[repr(C)] +pub struct ShouldNotDeriveDefault { + pub a: BlocklistMe, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldNotDeriveDefault", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ShouldNotDeriveDefault", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ShouldNotDeriveDefault::a", + ][::std::mem::offset_of!(ShouldNotDeriveDefault, a) - 0usize]; +}; +impl Default for ShouldNotDeriveDefault { + 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/derive-fn-ptr.rs b/bindgen-tests/tests/expectations/tests/derive-fn-ptr.rs new file mode 100644 index 0000000000..f4b09474ae --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-fn-ptr.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type my_fun_t = ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: ::std::os::raw::c_int, + arg5: ::std::os::raw::c_int, + arg6: ::std::os::raw::c_int, + arg7: ::std::os::raw::c_int, + arg8: ::std::os::raw::c_int, + arg9: ::std::os::raw::c_int, + arg10: ::std::os::raw::c_int, + arg11: ::std::os::raw::c_int, + arg12: ::std::os::raw::c_int, + arg13: ::std::os::raw::c_int, + arg14: ::std::os::raw::c_int, + arg15: ::std::os::raw::c_int, + arg16: ::std::os::raw::c_int, + ), +>; +#[repr(C)] +#[derive(Default, Copy, Clone)] +pub struct Foo { + pub callback: my_fun_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Foo::callback"][::std::mem::offset_of!(Foo, callback) - 0usize]; +}; +pub type my_fun2_t = ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: ::std::os::raw::c_int, + arg5: ::std::os::raw::c_int, + arg6: ::std::os::raw::c_int, + arg7: ::std::os::raw::c_int, + arg8: ::std::os::raw::c_int, + arg9: ::std::os::raw::c_int, + arg10: ::std::os::raw::c_int, + arg11: ::std::os::raw::c_int, + arg12: ::std::os::raw::c_int, + ), +>; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Bar { + pub callback: my_fun2_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::callback"][::std::mem::offset_of!(Bar, callback) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-hash-and-blocklist.rs b/bindgen-tests/tests/expectations/tests/derive-hash-and-blocklist.rs new file mode 100644 index 0000000000..c52047e8b8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-and-blocklist.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct BlocklistMe(u8); +/// Because this type contains a blocklisted type, it should not derive Hash. +#[repr(C)] +pub struct ShouldNotDeriveHash { + pub a: BlocklistMe, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldNotDeriveHash", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ShouldNotDeriveHash", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ShouldNotDeriveHash::a", + ][::std::mem::offset_of!(ShouldNotDeriveHash, a) - 0usize]; +}; +impl Default for ShouldNotDeriveHash { + 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/derive-hash-blocklisting.rs b/bindgen-tests/tests/expectations/tests/derive-hash-blocklisting.rs new file mode 100644 index 0000000000..e3223f08d7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-blocklisting.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] +pub struct Blocklisted { + t: T, + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, +} +/** This would derive(Hash, Eq, PartialEq) if it didn't contain a blocklisted type, + causing us to conservatively avoid deriving hash/Eq/PartialEq for it.*/ +#[repr(C)] +pub struct AllowlistedOne { + pub a: Blocklisted<::std::os::raw::c_int>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistedOne"][::std::mem::size_of::() - 4usize]; + ["Alignment of AllowlistedOne"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: AllowlistedOne::a", + ][::std::mem::offset_of!(AllowlistedOne, a) - 0usize]; +}; +impl Default for AllowlistedOne { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// This can't derive(Hash/Eq) even if it didn't contain a blocklisted type. +#[repr(C)] +pub struct AllowlistedTwo { + pub b: Blocklisted, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AllowlistedTwo"][::std::mem::size_of::() - 4usize]; + ["Alignment of AllowlistedTwo"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: AllowlistedTwo::b", + ][::std::mem::offset_of!(AllowlistedTwo, b) - 0usize]; +}; +impl Default for AllowlistedTwo { + 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/derive-hash-struct-with-anon-struct-float.rs b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs new file mode 100644 index 0000000000..2d66015fe7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] +pub struct foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] +pub struct foo__bindgen_ty_1 { + pub a: f32, + pub b: f32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-float-array.rs b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-float-array.rs new file mode 100644 index 0000000000..254a50b3e3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-float-array.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] +pub struct foo { + pub bar: [f32; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 12usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs new file mode 100644 index 0000000000..2588a49eed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs @@ -0,0 +1,80 @@ +#![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 const 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)] +#[derive(Debug, Default)] +pub struct test { + pub a: ::std::os::raw::c_int, + pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of test"][::std::mem::size_of::() - 4usize]; + ["Alignment of test"][::std::mem::align_of::() - 4usize]; + ["Offset of field: test::a"][::std::mem::offset_of!(test, a) - 0usize]; + [ + "Offset of field: test::zero_length_array", + ][::std::mem::offset_of!(test, zero_length_array) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct test2 { + pub a: ::std::os::raw::c_int, + pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of test2"][::std::mem::size_of::() - 4usize]; + ["Alignment of test2"][::std::mem::align_of::() - 4usize]; + ["Offset of field: test2::a"][::std::mem::offset_of!(test2, a) - 0usize]; + [ + "Offset of field: test2::incomplete_array", + ][::std::mem::offset_of!(test2, incomplete_array) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct test3 { + 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>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of test3"][::std::mem::size_of::() - 4usize]; + ["Alignment of test3"][::std::mem::align_of::() - 4usize]; + ["Offset of field: test3::a"][::std::mem::offset_of!(test3, a) - 0usize]; + [ + "Offset of field: test3::zero_length_array", + ][::std::mem::offset_of!(test3, zero_length_array) - 4usize]; + [ + "Offset of field: test3::incomplete_array", + ][::std::mem::offset_of!(test3, incomplete_array) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-pointer.rs b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-pointer.rs new file mode 100644 index 0000000000..5240d969db --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-struct-with-pointer.rs @@ -0,0 +1,92 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct ConstPtrMutObj { + pub bar: *mut ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ConstPtrMutObj"][::std::mem::size_of::() - 8usize]; + ["Alignment of ConstPtrMutObj"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ConstPtrMutObj::bar", + ][::std::mem::offset_of!(ConstPtrMutObj, bar) - 0usize]; +}; +impl Default for ConstPtrMutObj { + 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, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct MutPtrMutObj { + pub bar: *mut ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of MutPtrMutObj"][::std::mem::size_of::() - 8usize]; + ["Alignment of MutPtrMutObj"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: MutPtrMutObj::bar", + ][::std::mem::offset_of!(MutPtrMutObj, bar) - 0usize]; +}; +impl Default for MutPtrMutObj { + 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, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct MutPtrConstObj { + pub bar: *const ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of MutPtrConstObj"][::std::mem::size_of::() - 8usize]; + ["Alignment of MutPtrConstObj"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: MutPtrConstObj::bar", + ][::std::mem::offset_of!(MutPtrConstObj, bar) - 0usize]; +}; +impl Default for MutPtrConstObj { + 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, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct ConstPtrConstObj { + pub bar: *const ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ConstPtrConstObj"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of ConstPtrConstObj", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ConstPtrConstObj::bar", + ][::std::mem::offset_of!(ConstPtrConstObj, bar) - 0usize]; +}; +impl Default for ConstPtrConstObj { + 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/tests/expectations/tests/derive-hash-template-def-float.rs b/bindgen-tests/tests/expectations/tests/derive-hash-template-def-float.rs similarity index 84% rename from tests/expectations/tests/derive-hash-template-def-float.rs rename to bindgen-tests/tests/expectations/tests/derive-hash-template-def-float.rs index 5e07a61115..af09533cca 100644 --- a/tests/expectations/tests/derive-hash-template-def-float.rs +++ b/bindgen-tests/tests/expectations/tests/derive-hash-template-def-float.rs @@ -1,17 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] /// Template definition containing a float, which cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd. #[repr(C)] #[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] pub struct foo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub data: T, pub b: f32, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for foo { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/derive-hash-template-inst-float.rs b/bindgen-tests/tests/expectations/tests/derive-hash-template-inst-float.rs new file mode 100644 index 0000000000..10ed002e6e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-hash-template-inst-float.rs @@ -0,0 +1,77 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct foo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub data: T, +} +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() + } + } +} +/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct IntStr { + pub a: foo<::std::os::raw::c_int>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of IntStr"][::std::mem::size_of::() - 4usize]; + ["Alignment of IntStr"][::std::mem::align_of::() - 4usize]; + ["Offset of field: IntStr::a"][::std::mem::offset_of!(IntStr, a) - 0usize]; +}; +impl Default for IntStr { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] +pub struct FloatStr { + pub a: foo, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of FloatStr"][::std::mem::size_of::() - 4usize]; + ["Alignment of FloatStr"][::std::mem::align_of::() - 4usize]; + ["Offset of field: FloatStr::a"][::std::mem::offset_of!(FloatStr, a) - 0usize]; +}; +impl Default for FloatStr { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: foo_open0_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: foo_open0_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: foo_open0_float_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: foo_open0_float_close0", + ][::std::mem::align_of::>() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-and-blocklist.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-and-blocklist.rs new file mode 100644 index 0000000000..d24981061c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-and-blocklist.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct BlocklistMe(u8); +/** Because this type contains a blocklisted type, it should not derive + PartialEq.*/ +#[repr(C)] +pub struct ShouldNotDerivePartialEq { + pub a: BlocklistMe, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldNotDerivePartialEq", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ShouldNotDerivePartialEq", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ShouldNotDerivePartialEq::a", + ][::std::mem::offset_of!(ShouldNotDerivePartialEq, a) - 0usize]; +}; +impl Default for ShouldNotDerivePartialEq { + 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/derive-partialeq-anonfield.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-anonfield.rs new file mode 100644 index 0000000000..c4eb08df60 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-anonfield.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(64))] +#[derive(Copy, Clone)] +pub struct rte_mbuf { + pub __bindgen_anon_1: rte_mbuf__bindgen_ty_1, +} +#[repr(C)] +#[repr(align(1))] +#[derive(Copy, Clone)] +pub struct rte_mbuf__bindgen_ty_1 { + pub bindgen_union_field: [u8; 0usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_1", + ][::std::mem::size_of::() - 0usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_1", + ][::std::mem::align_of::() - 1usize]; +}; +impl Default for rte_mbuf__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_mbuf"][::std::mem::size_of::() - 0usize]; + ["Alignment of rte_mbuf"][::std::mem::align_of::() - 64usize]; +}; +impl Default for rte_mbuf { + 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/derive-partialeq-base.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs new file mode 100644 index 0000000000..3ca262fe36 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct Base { + pub large: [::std::os::raw::c_int; 33usize], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct ShouldDerivePartialEq { + pub _base: Base, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldDerivePartialEq", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs new file mode 100644 index 0000000000..b8da88e2a7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.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, PartialEq)] +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-partialeq-core.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs new file mode 100644 index 0000000000..9a36b8f8c7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +extern crate core; +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct C { + pub large_array: [::core::ffi::c_int; 420usize], +} +#[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(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-pointer.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-pointer.rs new file mode 100644 index 0000000000..3e48e5d8ce --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-pointer.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Bar { + pub b: *mut a, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::b"][::std::mem::offset_of!(Bar, b) - 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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct c { + pub __bindgen_anon_1: c__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union c__bindgen_ty_1 { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of c__bindgen_ty_1"][::std::mem::size_of::() - 1usize]; + ["Alignment of c__bindgen_ty_1"][::std::mem::align_of::() - 1usize]; +}; +impl Default for c__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of c"][::std::mem::size_of::() - 1usize]; + ["Alignment of c"][::std::mem::align_of::() - 1usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct a { + pub d: c, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of a"][::std::mem::size_of::
() - 1usize]; + ["Alignment of a"][::std::mem::align_of::() - 1usize]; + ["Offset of field: a::d"][::std::mem::offset_of!(a, d) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-union.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-union.rs new file mode 100644 index 0000000000..0365c765eb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-union.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// Deriving PartialEq for rust unions is not supported. +#[repr(C)] +#[derive(Copy, Clone)] +pub union ShouldNotDerivePartialEq { + pub a: ::std::os::raw::c_char, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldNotDerivePartialEq", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of ShouldNotDerivePartialEq", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ShouldNotDerivePartialEq::a", + ][::std::mem::offset_of!(ShouldNotDerivePartialEq, a) - 0usize]; + [ + "Offset of field: ShouldNotDerivePartialEq::b", + ][::std::mem::offset_of!(ShouldNotDerivePartialEq, b) - 0usize]; +}; +impl Default for ShouldNotDerivePartialEq { + 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/disable-namespacing.rs b/bindgen-tests/tests/expectations/tests/disable-namespacing.rs new file mode 100644 index 0000000000..4d9b6a082d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/disable-namespacing.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type Baz = ::std::os::raw::c_int; diff --git a/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs b/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs new file mode 100644 index 0000000000..757e0481aa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs @@ -0,0 +1,122 @@ +#![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 b1: bar1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar1 { + pub x1: ::std::os::raw::c_int, + pub b2: bar1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar1__bindgen_ty_1 { + pub x2: ::std::os::raw::c_int, + pub b3: bar1__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar1__bindgen_ty_1__bindgen_ty_1 { + pub x3: ::std::os::raw::c_int, + pub b4: bar4, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar4 { + pub x4: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar4"][::std::mem::size_of::() - 4usize]; + ["Alignment of bar4"][::std::mem::align_of::() - 4usize]; + ["Offset of field: bar4::x4"][::std::mem::offset_of!(bar4, x4) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of bar1__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of bar1__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: bar1__bindgen_ty_1__bindgen_ty_1::x3", + ][::std::mem::offset_of!(bar1__bindgen_ty_1__bindgen_ty_1, x3) - 0usize]; + [ + "Offset of field: bar1__bindgen_ty_1__bindgen_ty_1::b4", + ][::std::mem::offset_of!(bar1__bindgen_ty_1__bindgen_ty_1, b4) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of bar1__bindgen_ty_1", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of bar1__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: bar1__bindgen_ty_1::x2", + ][::std::mem::offset_of!(bar1__bindgen_ty_1, x2) - 0usize]; + [ + "Offset of field: bar1__bindgen_ty_1::b3", + ][::std::mem::offset_of!(bar1__bindgen_ty_1, b3) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar1"][::std::mem::size_of::() - 16usize]; + ["Alignment of bar1"][::std::mem::align_of::() - 4usize]; + ["Offset of field: bar1::x1"][::std::mem::offset_of!(bar1, x1) - 0usize]; + ["Offset of field: bar1::b2"][::std::mem::offset_of!(bar1, b2) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 16usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::b1"][::std::mem::offset_of!(foo, b1) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct _bindgen_ty_1 { + pub anon2: _bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct _bindgen_ty_1__bindgen_ty_1 { + pub b: baz, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct baz { + pub x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of baz"][::std::mem::align_of::() - 4usize]; + ["Offset of field: baz::x"][::std::mem::offset_of!(baz, x) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of _bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::<_bindgen_ty_1__bindgen_ty_1>() - 4usize]; + [ + "Alignment of _bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::<_bindgen_ty_1__bindgen_ty_1>() - 4usize]; + [ + "Offset of field: _bindgen_ty_1__bindgen_ty_1::b", + ][::std::mem::offset_of!(_bindgen_ty_1__bindgen_ty_1, b) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 4usize]; + ["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 4usize]; + [ + "Offset of field: _bindgen_ty_1::anon2", + ][::std::mem::offset_of!(_bindgen_ty_1, anon2) - 0usize]; +}; +unsafe extern "C" { + pub static mut anon1: _bindgen_ty_1; +} diff --git a/bindgen-tests/tests/expectations/tests/disable-untagged-union.rs b/bindgen-tests/tests/expectations/tests/disable-untagged-union.rs new file mode 100644 index 0000000000..60636280e4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/disable-untagged-union.rs @@ -0,0 +1,58 @@ +#![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 const 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)] +pub struct Foo { + pub bar: __BindgenUnionField<::std::os::raw::c_int>, + pub baz: __BindgenUnionField<::std::os::raw::c_uint>, + pub bindgen_union_field: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; + ["Offset of field: Foo::baz"][::std::mem::offset_of!(Foo, baz) - 0usize]; +}; 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 new file mode 100644 index 0000000000..37139d3136 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -0,0 +1,186 @@ +#![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, Default, Copy, Clone)] +pub struct WithBitfield { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub a: ::std::os::raw::c_uint, +} +impl WithBitfield { + #[inline] + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithBitfieldAndAttrPacked { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub a: ::std::os::raw::c_uint, +} +impl WithBitfieldAndAttrPacked { + #[inline] + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithBitfieldAndPacked { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub a: ::std::os::raw::c_uint, +} +impl WithBitfieldAndPacked { + #[inline] + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/do-not-derive-copy.rs b/bindgen-tests/tests/expectations/tests/do-not-derive-copy.rs new file mode 100644 index 0000000000..29ca6d6acf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/do-not-derive-copy.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct WouldBeCopyButWeAreNotDerivingCopy { + pub x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of WouldBeCopyButWeAreNotDerivingCopy", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WouldBeCopyButWeAreNotDerivingCopy", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WouldBeCopyButWeAreNotDerivingCopy::x", + ][::std::mem::offset_of!(WouldBeCopyButWeAreNotDerivingCopy, x) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/doggo-or-null.rs b/bindgen-tests/tests/expectations/tests/doggo-or-null.rs new file mode 100644 index 0000000000..972da871d3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/doggo-or-null.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq)] +pub struct Doggo { + pub x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Doggo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Doggo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Doggo::x"][::std::mem::offset_of!(Doggo, x) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq)] +pub struct Null { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Null"][::std::mem::size_of::() - 1usize]; + ["Alignment of Null"][::std::mem::align_of::() - 1usize]; +}; +/** This type is an opaque union. Unions can't derive anything interesting like + Debug or Default, even if their layout can, because it would require knowing + which variant is in use. Opaque unions still end up as a `union` in the Rust + bindings, but they just have one variant. Even so, can't derive. We should + probably emit an opaque struct for opaque unions... but until then, we have + this test to make sure that opaque unions don't derive and still compile.*/ +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub union DoggoOrNull { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of DoggoOrNull"][::std::mem::size_of::() - 4usize]; + ["Alignment of DoggoOrNull"][::std::mem::align_of::() - 4usize]; +}; +impl Default for DoggoOrNull { + 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/tests/expectations/tests/dupe-enum-variant-in-namespace.rs b/bindgen-tests/tests/expectations/tests/dupe-enum-variant-in-namespace.rs similarity index 85% rename from tests/expectations/tests/dupe-enum-variant-in-namespace.rs rename to bindgen-tests/tests/expectations/tests/dupe-enum-variant-in-namespace.rs index 85e4539253..d521bcc17b 100644 --- a/tests/expectations/tests/dupe-enum-variant-in-namespace.rs +++ b/bindgen-tests/tests/expectations/tests/dupe-enum-variant-in-namespace.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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)] diff --git a/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs b/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs new file mode 100644 index 0000000000..86e1edbbf9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct BitStream { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of BitStream"][::std::mem::size_of::() - 1usize]; + ["Alignment of BitStream"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN9BitStream5WriteEPKcj"] + pub fn BitStream_Write( + this: *mut BitStream, + inputByteArray: *const ::std::os::raw::c_char, + numberOfBytes: ::std::os::raw::c_uint, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN9BitStream5WriteEPS_j"] + pub fn BitStream_Write1( + this: *mut BitStream, + bitStream: *mut BitStream, + numberOfBits: ::std::os::raw::c_uint, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN9BitStream6Write1Ev"] + pub fn BitStream_Write11(this: *mut BitStream); +} +impl BitStream { + #[inline] + pub unsafe fn Write( + &mut self, + inputByteArray: *const ::std::os::raw::c_char, + numberOfBytes: ::std::os::raw::c_uint, + ) { + BitStream_Write(self, inputByteArray, numberOfBytes) + } + #[inline] + pub unsafe fn Write1( + &mut self, + bitStream: *mut BitStream, + numberOfBits: ::std::os::raw::c_uint, + ) { + BitStream_Write1(self, bitStream, numberOfBits) + } + #[inline] + pub unsafe fn Write11(&mut self) { + BitStream_Write11(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/duplicated-namespaces-definitions.rs b/bindgen-tests/tests/expectations/tests/duplicated-namespaces-definitions.rs new file mode 100644 index 0000000000..775a21ac30 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/duplicated-namespaces-definitions.rs @@ -0,0 +1,47 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar { + pub foo: ::std::os::raw::c_int, + pub baz: bool, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Bar::foo"][::std::mem::offset_of!(Bar, foo) - 0usize]; + ["Offset of field: Bar::baz"][::std::mem::offset_of!(Bar, baz) - 4usize]; + }; + } + pub mod bar { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct Foo { + pub ptr: *mut root::foo::Bar, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Foo::ptr"][::std::mem::offset_of!(Foo, ptr) - 0usize]; + }; + 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() + } + } + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/duplicated-namespaces.rs b/bindgen-tests/tests/expectations/tests/duplicated-namespaces.rs new file mode 100644 index 0000000000..c652d151b8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/duplicated-namespaces.rs @@ -0,0 +1,6 @@ +#![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; +} diff --git a/tests/expectations/tests/duplicated_constants_in_ns.rs b/bindgen-tests/tests/expectations/tests/duplicated_constants_in_ns.rs similarity index 80% rename from tests/expectations/tests/duplicated_constants_in_ns.rs rename to bindgen-tests/tests/expectations/tests/duplicated_constants_in_ns.rs index 3b3405db5c..2f676374ae 100644 --- a/tests/expectations/tests/duplicated_constants_in_ns.rs +++ b/bindgen-tests/tests/expectations/tests/duplicated_constants_in_ns.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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)] diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_attributes.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_attributes.rs new file mode 100644 index 0000000000..a1fb1b0cc1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_attributes.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + pub baz: unsafe extern "C" fn() -> ::std::os::raw::c_int, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + 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)?; + Ok(TestLib { __library, foo, baz }) + } + #[must_use] + /** @brief A function + + @param x + @param y + @return int*/ + pub unsafe fn foo( + &self, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int { + (self.foo)(x, y) + } + pub unsafe fn baz(&self) -> ::std::os::raw::c_int { + (self.baz)() + } +} diff --git a/tests/expectations/tests/dynamic_loading_required.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_required.rs similarity index 79% rename from tests/expectations/tests/dynamic_loading_required.rs rename to bindgen-tests/tests/expectations/tests/dynamic_loading_required.rs index e46ffd49e0..5c929ffc3d 100644 --- a/tests/expectations/tests/dynamic_loading_required.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_required.rs @@ -1,11 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate libloading; +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub struct TestLib { __library: ::libloading::Library, pub foo: unsafe extern "C" fn( @@ -25,9 +18,7 @@ impl TestLib { let library = ::libloading::Library::new(path)?; Self::from_library(library) } - pub unsafe fn from_library( - library: L, - ) -> Result + pub unsafe fn from_library(library: L) -> Result where L: Into<::libloading::Library>, { @@ -49,10 +40,7 @@ impl TestLib { ) -> ::std::os::raw::c_int { (self.foo)(x, y) } - pub unsafe fn bar( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { + pub unsafe fn bar(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { (self.bar)(x) } pub unsafe fn baz(&self) -> ::std::os::raw::c_int { diff --git a/tests/expectations/tests/dynamic_loading_simple.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_simple.rs similarity index 76% rename from tests/expectations/tests/dynamic_loading_simple.rs rename to bindgen-tests/tests/expectations/tests/dynamic_loading_simple.rs index cae5bd6937..9a4cfaf570 100644 --- a/tests/expectations/tests/dynamic_loading_simple.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_simple.rs @@ -1,11 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate libloading; +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub struct TestLib { __library: ::libloading::Library, pub foo: Result< @@ -16,9 +9,7 @@ pub struct TestLib { ::libloading::Error, >, pub bar: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, ::libloading::Error, >, pub baz: Result< @@ -34,9 +25,7 @@ impl TestLib { let library = ::libloading::Library::new(path)?; Self::from_library(library) } - pub unsafe fn from_library( - library: L, - ) -> Result + pub unsafe fn from_library(library: L) -> Result where L: Into<::libloading::Library>, { @@ -58,10 +47,7 @@ impl TestLib { ) -> ::std::os::raw::c_int { (self.foo.as_ref().expect("Expected function, got error."))(x, y) } - pub unsafe fn bar( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { + pub unsafe fn bar(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { (self.bar.as_ref().expect("Expected function, got error."))(x) } pub unsafe fn baz(&self) -> ::std::os::raw::c_int { diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs new file mode 100644 index 0000000000..1f63a7893f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result< + unsafe extern "C" fn(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub foo1: Result f32, ::libloading::Error>, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + 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 { + (self.foo.as_ref().expect("Expected function, got error."))(x) + } + pub unsafe fn foo1(&self, x: f32) -> f32 { + (self.foo1.as_ref().expect("Expected function, got error."))(x) + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_required.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_required.rs new file mode 100644 index 0000000000..a96efbe546 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_required.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: *mut ::std::os::raw::c_int, + pub baz: *mut *mut ::std::os::raw::c_int, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let foo = __library.get::<*mut ::std::os::raw::c_int>(b"foo\0").map(|sym| *sym)?; + let baz = __library + .get::<*mut *mut ::std::os::raw::c_int>(b"baz\0") + .map(|sym| *sym)?; + Ok(TestLib { __library, foo, baz }) + } + pub unsafe fn foo(&self) -> *mut ::std::os::raw::c_int { + self.foo + } + pub unsafe fn baz(&self) -> *mut *mut ::std::os::raw::c_int { + self.baz + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_simple.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_simple.rs new file mode 100644 index 0000000000..ced70dbdba --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_simple.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result<*mut ::std::os::raw::c_int, ::libloading::Error>, + pub baz: Result<*mut *mut ::std::os::raw::c_int, ::libloading::Error>, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let foo = __library.get::<*mut ::std::os::raw::c_int>(b"foo\0").map(|sym| *sym); + let baz = __library + .get::<*mut *mut ::std::os::raw::c_int>(b"baz\0") + .map(|sym| *sym); + Ok(TestLib { __library, foo, baz }) + } + pub unsafe fn foo(&self) -> *mut ::std::os::raw::c_int { + *self.foo.as_ref().expect("Expected variable, got error.") + } + pub unsafe fn baz(&self) -> *mut *mut ::std::os::raw::c_int { + *self.baz.as_ref().expect("Expected variable, got error.") + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_with_allowlist.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_with_allowlist.rs new file mode 100644 index 0000000000..3f29e73814 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_variable_with_allowlist.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result<*mut ::std::os::raw::c_int, ::libloading::Error>, + pub bar: Result<*mut ::std::os::raw::c_int, ::libloading::Error>, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let foo = __library.get::<*mut ::std::os::raw::c_int>(b"foo\0").map(|sym| *sym); + let bar = __library.get::<*mut ::std::os::raw::c_int>(b"bar\0").map(|sym| *sym); + Ok(TestLib { __library, foo, bar }) + } + pub unsafe fn foo(&self) -> *mut ::std::os::raw::c_int { + *self.foo.as_ref().expect("Expected variable, got error.") + } + pub unsafe fn bar(&self) -> *mut ::std::os::raw::c_int { + *self.bar.as_ref().expect("Expected variable, got error.") + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs new file mode 100644 index 0000000000..34ebe8d9a5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub baz: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub bazz: Result< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int, ...) -> ::std::os::raw::c_int, + ::libloading::Error, + >, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + 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, + baz, + bazz, + }) + } + pub unsafe fn foo(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { + (self.foo.as_ref().expect("Expected function, got error."))(x) + } + pub unsafe fn baz(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { + (self.baz.as_ref().expect("Expected function, got error."))(x) + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs new file mode 100644 index 0000000000..8c86674f7a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs @@ -0,0 +1,75 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct X { + pub _x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of X"][::std::mem::size_of::() - 4usize]; + ["Alignment of X"][::std::mem::align_of::() - 4usize]; + ["Offset of field: X::_x"][::std::mem::offset_of!(X, _x) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1X13some_functionEv"] + pub fn X_some_function(this: *mut X); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1X19some_other_functionEv"] + pub fn X_some_other_function(this: *mut X); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1XC1Ei"] + pub fn X_X(this: *mut X, x: ::std::os::raw::c_int); +} +impl X { + #[inline] + pub unsafe fn some_function(&mut self) { + X_some_function(self) + } + #[inline] + pub unsafe fn some_other_function(&mut self) { + X_some_other_function(self) + } + #[inline] + pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + X_X(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } +} +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub bar: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + 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 { + (self.foo.as_ref().expect("Expected function, got error."))(x) + } + pub unsafe fn bar(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { + (self.bar.as_ref().expect("Expected function, got error."))(x) + } +} diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs new file mode 100644 index 0000000000..65ff2b2f72 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs @@ -0,0 +1,72 @@ +#![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 _x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 4usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::_x"][::std::mem::offset_of!(A, _x) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1A13some_functionEv"] + pub fn A_some_function(this: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1A19some_other_functionEv"] + pub fn A_some_other_function(this: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1AC1Ei"] + pub fn A_A(this: *mut A, x: ::std::os::raw::c_int); +} +impl A { + #[inline] + pub unsafe fn some_function(&mut self) { + A_some_function(self) + } + #[inline] + pub unsafe fn some_other_function(&mut self) { + A_some_other_function(self) + } + #[inline] + pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + A_A(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } +} +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub bar: Result, +} +impl TestLib { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + 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 { + (self.foo.as_ref().expect("Expected function, got error."))(x) + } + pub unsafe fn bar(&self) { + (self.bar.as_ref().expect("Expected function, got error."))() + } +} diff --git a/bindgen-tests/tests/expectations/tests/elaborated.rs b/bindgen-tests/tests/expectations/tests/elaborated.rs new file mode 100644 index 0000000000..81c0733089 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/elaborated.rs @@ -0,0 +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; +unsafe extern "C" { + #[link_name = "\u{1}_Z9somethingPKi"] + pub fn something(wat: *const whatever_whatever_t); +} diff --git a/tests/expectations/tests/empty-enum.rs b/bindgen-tests/tests/expectations/tests/empty-enum.rs similarity index 78% rename from tests/expectations/tests/empty-enum.rs rename to bindgen-tests/tests/expectations/tests/empty-enum.rs index fe188b3e3e..d19aa41845 100644 --- a/tests/expectations/tests/empty-enum.rs +++ b/bindgen-tests/tests/expectations/tests/empty-enum.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type EmptyConstified = ::std::os::raw::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -12,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)] @@ -21,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)] @@ -30,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/tests/expectations/tests/empty-union.rs b/bindgen-tests/tests/expectations/tests/empty-union.rs similarity index 76% rename from tests/expectations/tests/empty-union.rs rename to bindgen-tests/tests/expectations/tests/empty-union.rs index c21ae2f01f..de0f806eb5 100644 --- a/tests/expectations/tests/empty-union.rs +++ b/bindgen-tests/tests/expectations/tests/empty-union.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Copy, Clone)] pub union a__bindgen_ty_1 { diff --git a/bindgen-tests/tests/expectations/tests/empty_template_param_name.rs b/bindgen-tests/tests/expectations/tests/empty_template_param_name.rs new file mode 100644 index 0000000000..db5764ab25 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/empty_template_param_name.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type __void_t = ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct __iterator_traits { + pub _address: u8, +} diff --git a/tests/expectations/tests/enum-default-bitfield.rs b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs similarity index 83% rename from tests/expectations/tests/enum-default-bitfield.rs rename to bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs index 1dc27fdc40..dda688617c 100644 --- a/tests/expectations/tests/enum-default-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct foo { @@ -41,29 +35,12 @@ impl ::std::ops::BitAndAssign for foo__bindgen_ty_1 { #[repr(transparent)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct foo__bindgen_ty_1(pub ::std::os::raw::c_uint); -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; impl Default for foo { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -75,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 { @@ -109,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 { @@ -151,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 { @@ -184,4 +157,4 @@ impl ::std::ops::BitAndAssign for Debug { #[repr(transparent)] ///

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Debug(pub ::std::os::raw::c_uint); \ No newline at end of file +pub struct Debug(pub ::std::os::raw::c_uint); diff --git a/bindgen-tests/tests/expectations/tests/enum-default-consts.rs b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs new file mode 100644 index 0000000000..1432182310 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub member: foo__bindgen_ty_1, +} +pub const foo_FOO_A: foo__bindgen_ty_1 = 0; +pub const foo_FOO_B: foo__bindgen_ty_1 = 1; +pub type foo__bindgen_ty_1 = ::std::os::raw::c_uint; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; +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() + } + } +} +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; +} +pub const NoDebug_NoDebug1: NoDebug = 0; +pub const NoDebug_NoDebug2: NoDebug = 1; +///
+pub type NoDebug = ::std::os::raw::c_uint; +pub const Debug_Debug1: Debug = 0; +pub const Debug_Debug2: Debug = 1; +///
+pub type Debug = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/enum-default-module.rs b/bindgen-tests/tests/expectations/tests/enum-default-module.rs new file mode 100644 index 0000000000..23fbd22c6e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-default-module.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +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; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; +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() + } + } +} +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; + pub const Debug2: Type = 1; +} diff --git a/tests/expectations/tests/enum-default-rust.d b/bindgen-tests/tests/expectations/tests/enum-default-rust.d similarity index 100% rename from tests/expectations/tests/enum-default-rust.d rename to bindgen-tests/tests/expectations/tests/enum-default-rust.d diff --git a/bindgen-tests/tests/expectations/tests/enum-default-rust.rs b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs new file mode 100644 index 0000000000..59901a78ac --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub member: foo__bindgen_ty_1, +} +pub const foo_FOO_A: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_A; +pub const foo_FOO_B: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_B; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum foo__bindgen_ty_1 { + FOO_A = 0, + FOO_B = 1, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; +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() + } + } +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + Bar = 0, + 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; +} +#[repr(u32)] +///
+#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum NoDebug { + NoDebug1 = 0, + NoDebug2 = 1, +} +#[repr(u32)] +///
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Debug { + Debug1 = 0, + Debug2 = 1, +} diff --git a/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs b/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs new file mode 100644 index 0000000000..33eec3e44f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +impl B { + /// Document field with three slashes + pub const VAR_A: B = B(0); + /// Document field with preceding star + pub const VAR_B: B = B(1); + /// Document field with preceding exclamation + pub const VAR_C: B = B(2); + ///< Document field with following star + pub const VAR_D: B = B(3); + ///< Document field with following exclamation + pub const VAR_E: B = B(4); + /** Document field with preceding star, with a loong long multiline + comment. + + Very interesting documentation, definitely.*/ + pub const VAR_F: B = B(5); +} +impl ::std::ops::BitOr for B { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + B(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for B { + #[inline] + fn bitor_assign(&mut self, rhs: B) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for B { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + B(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for B { + #[inline] + fn bitand_assign(&mut self, rhs: B) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +/// Document enum +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct B(pub ::std::os::raw::c_uint); diff --git a/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs b/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs new file mode 100644 index 0000000000..580d8165ac --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs @@ -0,0 +1,22 @@ +#![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 + pub const VAR_A: Type = 0; + /// Document field with preceding star + pub const VAR_B: Type = 1; + /// Document field with preceding exclamation + pub const VAR_C: Type = 2; + ///< Document field with following star + pub const VAR_D: Type = 3; + ///< Document field with following exclamation + pub const VAR_E: Type = 4; + /** Document field with preceding star, with a loong long multiline + comment. + + Very interesting documentation, definitely.*/ + pub const VAR_F: Type = 5; +} 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-doc-rusty.rs b/bindgen-tests/tests/expectations/tests/enum-doc-rusty.rs new file mode 100644 index 0000000000..3eec0759c5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-doc-rusty.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(u32)] +/// 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-doc.rs b/bindgen-tests/tests/expectations/tests/enum-doc.rs new file mode 100644 index 0000000000..98a7eed8f8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-doc.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/// Document field with three slashes +pub const B_VAR_A: B = 0; +/// Document field with preceding star +pub const B_VAR_B: B = 1; +/// Document field with preceding exclamation +pub const B_VAR_C: B = 2; +///< Document field with following star +pub const B_VAR_D: B = 3; +///< Document field with following exclamation +pub const B_VAR_E: B = 4; +/** Document field with preceding star, with a loong long multiline + comment. + + Very interesting documentation, definitely.*/ +pub const B_VAR_F: B = 5; +/// Document enum +pub type B = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs new file mode 100644 index 0000000000..643577e1e3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct foo { + pub member: foo__bindgen_ty_1, +} +pub const foo_FOO_A: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_A; +pub const foo_FOO_B: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_B; +#[repr(u32)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum foo__bindgen_ty_1 { + FOO_A = 0, + FOO_B = 1, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; +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() + } + } +} +#[repr(u32)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + Bar = 0, + 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; +} +#[repr(u32)] +///
+#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum NoDebug { + NoDebug1 = 0, + NoDebug2 = 1, +} +#[repr(u32)] +///
+#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub enum Debug { + Debug1 = 0, + Debug2 = 1, +} diff --git a/bindgen-tests/tests/expectations/tests/enum-translate-type.rs b/bindgen-tests/tests/expectations/tests/enum-translate-type.rs new file mode 100644 index 0000000000..2431e48d5b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-translate-type.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const my_enum1_A: my_enum1 = 0; +pub type my_enum1 = u32; +pub const my_enum2_B: my_enum2 = -1; +pub type my_enum2 = i32; +pub const my_enum3_C: my_enum3 = 0; +pub type my_enum3 = i16; +pub const my_enum4_D: my_enum4 = 255; +pub type my_enum4 = u8; diff --git a/bindgen-tests/tests/expectations/tests/enum-typedef.rs b/bindgen-tests/tests/expectations/tests/enum-typedef.rs new file mode 100644 index 0000000000..772184b39f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-typedef.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const Enum_Variant: Enum = 0; +pub type Enum = i16; +pub type TypedefFirst = i16; +pub const TypedefFirst_Variant2: TypedefFirst = 0; diff --git a/bindgen-tests/tests/expectations/tests/enum-undefault.rs b/bindgen-tests/tests/expectations/tests/enum-undefault.rs new file mode 100644 index 0000000000..01a7aa3cea --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-undefault.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + Bar = 0, + Qux = 1, +} +pub const Neg_MinusOne: Neg = -1; +pub const Neg_One: Neg = 1; +pub type Neg = ::std::os::raw::c_int; diff --git a/bindgen-tests/tests/expectations/tests/enum-variant-replaces.rs b/bindgen-tests/tests/expectations/tests/enum-variant-replaces.rs new file mode 100644 index 0000000000..a661ca833b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-variant-replaces.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/**
+ + Should see PASS below.*/ +pub const OGRErr_PASS: OGRErr = 0; +/**
+ + Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below.*/ +pub const OGRErr_OGRERR_NONE: OGRErr = 1; +///
+pub type OGRErr = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/enum.rs b/bindgen-tests/tests/expectations/tests/enum.rs new file mode 100644 index 0000000000..820182125a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub member: foo__bindgen_ty_1, +} +pub const foo_FOO_A: foo__bindgen_ty_1 = 0; +pub const foo_FOO_B: foo__bindgen_ty_1 = 1; +pub type foo__bindgen_ty_1 = ::std::os::raw::c_uint; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::member"][::std::mem::offset_of!(foo, member) - 0usize]; +}; +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() + } + } +} +pub const Foo_Bar: Foo = 0; +pub const Foo_Qux: Foo = 1; +pub type Foo = ::std::os::raw::c_uint; +pub const Neg_MinusOne: Neg = -1; +pub const Neg_One: Neg = 1; +pub type Neg = ::std::os::raw::c_int; +pub const NoDebug_NoDebug1: NoDebug = 0; +pub const NoDebug_NoDebug2: NoDebug = 1; +///
+pub type NoDebug = ::std::os::raw::c_uint; +pub const Debug_Debug1: Debug = 0; +pub const Debug_Debug2: Debug = 1; +///
+pub type Debug = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/enum_alias.rs b/bindgen-tests/tests/expectations/tests/enum_alias.rs new file mode 100644 index 0000000000..0d29768837 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum_alias.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(u8)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Bar { + VAL = 0, +} diff --git a/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs b/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs new file mode 100644 index 0000000000..0a7e16d6dd --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const match_: _bindgen_ty_1 = _bindgen_ty_1::match_; +pub const whatever_else: _bindgen_ty_1 = _bindgen_ty_1::whatever_else; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + match_ = 0, + whatever_else = 1, +} +#[repr(C)] +pub struct C__bindgen_vtable { + pub C_match: unsafe extern "C" fn(this: *mut C), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct C { + pub vtable_: *const C__bindgen_vtable, + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 16usize]; + ["Alignment of C"][::std::mem::align_of::() - 8usize]; + ["Offset of field: C::i"][::std::mem::offset_of!(C, i) - 8usize]; +}; +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() + } + } +} +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/enum_dupe.rs b/bindgen-tests/tests/expectations/tests/enum_dupe.rs new file mode 100644 index 0000000000..3ee4c68cbd --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum_dupe.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +impl Foo { + pub const Dupe: Foo = Foo::Bar; +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + Bar = 1, +} diff --git a/tests/expectations/tests/enum_explicit_type.rs b/bindgen-tests/tests/expectations/tests/enum_explicit_type.rs similarity index 79% rename from tests/expectations/tests/enum_explicit_type.rs rename to bindgen-tests/tests/expectations/tests/enum_explicit_type.rs index 29bc5d8cfc..1f3dd36f96 100644 --- a/tests/expectations/tests/enum_explicit_type.rs +++ b/bindgen-tests/tests/expectations/tests/enum_explicit_type.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum Foo { @@ -49,10 +43,8 @@ pub type MyType = bool; pub enum BoolEnumsAreFun2 { Value2 = 1, } -pub const AnonymousVariantOne: _bindgen_ty_1 = - _bindgen_ty_1::AnonymousVariantOne; -pub const AnonymousVariantTwo: _bindgen_ty_1 = - _bindgen_ty_1::AnonymousVariantTwo; +pub const AnonymousVariantOne: _bindgen_ty_1 = _bindgen_ty_1::AnonymousVariantOne; +pub const AnonymousVariantTwo: _bindgen_ty_1 = _bindgen_ty_1::AnonymousVariantTwo; #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum _bindgen_ty_1 { diff --git a/tests/expectations/tests/enum_explicit_type_constants.rs b/bindgen-tests/tests/expectations/tests/enum_explicit_type_constants.rs similarity index 80% rename from tests/expectations/tests/enum_explicit_type_constants.rs rename to bindgen-tests/tests/expectations/tests/enum_explicit_type_constants.rs index 030d64bedc..8f310572b6 100644 --- a/tests/expectations/tests/enum_explicit_type_constants.rs +++ b/bindgen-tests/tests/expectations/tests/enum_explicit_type_constants.rs @@ -1,10 +1,5 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(target_os = "windows"))] pub const Foo_Bar: Foo = 0; pub const Foo_Qux: Foo = 1; pub type Foo = ::std::os::raw::c_uchar; @@ -25,6 +20,6 @@ pub type BoolEnumsAreFun = bool; pub type MyType = bool; pub const BoolEnumsAreFun2_Value2: BoolEnumsAreFun2 = true; pub type BoolEnumsAreFun2 = MyType; -pub const AnonymousVariantOne: ::std::os::raw::c_uchar = 0; -pub const AnonymousVariantTwo: ::std::os::raw::c_uchar = 1; +pub const AnonymousVariantOne: _bindgen_ty_1 = 0; +pub const AnonymousVariantTwo: _bindgen_ty_1 = 1; pub type _bindgen_ty_1 = ::std::os::raw::c_uchar; diff --git a/bindgen-tests/tests/expectations/tests/enum_in_template.rs b/bindgen-tests/tests/expectations/tests/enum_in_template.rs new file mode 100644 index 0000000000..e54a97b5f4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum_in_template.rs @@ -0,0 +1,9 @@ +#![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, +} +pub const Foo_Bar_A: Foo_Bar = 0; +pub const Foo_Bar_B: Foo_Bar = 0; +pub type Foo_Bar = i32; diff --git a/tests/expectations/tests/enum_in_template_with_typedef.rs b/bindgen-tests/tests/expectations/tests/enum_in_template_with_typedef.rs similarity index 79% rename from tests/expectations/tests/enum_in_template_with_typedef.rs rename to bindgen-tests/tests/expectations/tests/enum_in_template_with_typedef.rs index 75dce30c0e..b71923e10f 100644 --- a/tests/expectations/tests/enum_in_template_with_typedef.rs +++ b/bindgen-tests/tests/expectations/tests/enum_in_template_with_typedef.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct std_fbstring_core { diff --git a/bindgen-tests/tests/expectations/tests/enum_negative.rs b/bindgen-tests/tests/expectations/tests/enum_negative.rs new file mode 100644 index 0000000000..f946e0f044 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum_negative.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + Bar = -2, + Qux = 1, +} diff --git a/tests/expectations/tests/enum_packed.rs b/bindgen-tests/tests/expectations/tests/enum_packed.rs similarity index 76% rename from tests/expectations/tests/enum_packed.rs rename to bindgen-tests/tests/expectations/tests/enum_packed.rs index 89b0da461d..d4ec2192d1 100644 --- a/tests/expectations/tests/enum_packed.rs +++ b/bindgen-tests/tests/expectations/tests/enum_packed.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum Foo { diff --git a/bindgen-tests/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs b/bindgen-tests/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs new file mode 100644 index 0000000000..79004238fc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs @@ -0,0 +1,3 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![allow(overflowing_literals)] +pub const a: u32 = 4294967291; diff --git a/bindgen-tests/tests/expectations/tests/eval-value-dependent.rs b/bindgen-tests/tests/expectations/tests/eval-value-dependent.rs new file mode 100644 index 0000000000..b9b2709cfa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/eval-value-dependent.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct e { + pub _address: u8, +} +pub type e_f = d; diff --git a/bindgen-tests/tests/expectations/tests/eval-variadic-template-parameter.rs b/bindgen-tests/tests/expectations/tests/eval-variadic-template-parameter.rs new file mode 100644 index 0000000000..fccd2ad5d7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/eval-variadic-template-parameter.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/explicit-padding.rs b/bindgen-tests/tests/expectations/tests/explicit-padding.rs new file mode 100644 index 0000000000..ec21399106 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/explicit-padding.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pad_me { + pub first: u8, + pub __bindgen_padding_0: [u8; 3usize], + pub second: u32, + pub third: u16, + pub __bindgen_padding_1: [u8; 2usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pad_me"][::std::mem::size_of::() - 12usize]; + ["Alignment of pad_me"][::std::mem::align_of::() - 4usize]; + ["Offset of field: pad_me::first"][::std::mem::offset_of!(pad_me, first) - 0usize]; + ["Offset of field: pad_me::second"][::std::mem::offset_of!(pad_me, second) - 4usize]; + ["Offset of field: pad_me::third"][::std::mem::offset_of!(pad_me, third) - 8usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub union dont_pad_me { + pub first: u8, + pub second: u32, + pub third: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of dont_pad_me"][::std::mem::size_of::() - 4usize]; + ["Alignment of dont_pad_me"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: dont_pad_me::first", + ][::std::mem::offset_of!(dont_pad_me, first) - 0usize]; + [ + "Offset of field: dont_pad_me::second", + ][::std::mem::offset_of!(dont_pad_me, second) - 0usize]; + [ + "Offset of field: dont_pad_me::third", + ][::std::mem::offset_of!(dont_pad_me, third) - 0usize]; +}; +impl Default for dont_pad_me { + 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/extern-const-struct.rs b/bindgen-tests/tests/expectations/tests/extern-const-struct.rs new file mode 100644 index 0000000000..7085bef5c8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern-const-struct.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsFoo { + pub details: [f32; 400usize], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +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.rs b/bindgen-tests/tests/expectations/tests/extern.rs new file mode 100644 index 0000000000..496f595a0d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type foo = ::std::option::Option< + unsafe extern "C" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int, +>; 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 new file mode 100644 index 0000000000..99ca3d4b9b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs @@ -0,0 +1,264 @@ +#![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, Default, Copy, Clone)] +pub struct my_struct { + pub a: ::std::os::raw::c_int, + private_b: ::std::os::raw::c_int, + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of my_struct"][::std::mem::size_of::() - 12usize]; + ["Alignment of my_struct"][::std::mem::align_of::() - 4usize]; + ["Offset of field: my_struct::a"][::std::mem::offset_of!(my_struct, a) - 0usize]; + [ + "Offset of field: my_struct::private_b", + ][::std::mem::offset_of!(my_struct, private_b) - 4usize]; +}; +impl my_struct { + #[inline] + pub fn c(&self) -> ::std::os::raw::c_int { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) 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(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_private_d(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let c: u32 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let private_d: u32 = unsafe { ::std::mem::transmute(private_d) }; + private_d as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/field-visibility.rs b/bindgen-tests/tests/expectations/tests/field-visibility.rs new file mode 100644 index 0000000000..13a1d9a543 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/field-visibility.rs @@ -0,0 +1,277 @@ +#![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, Default, Copy, Clone)] +pub struct my_struct1 { + pub _bindgen_align: [u32; 0], + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of my_struct1"][::std::mem::size_of::() - 4usize]; + ["Alignment of my_struct1"][::std::mem::align_of::() - 4usize]; +}; +impl my_struct1 { + #[inline] + fn a(&self) -> ::std::os::raw::c_int { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + fn set_a(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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 + .set( + 0usize, + 1u8, + { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct my_struct2 { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of my_struct2"][::std::mem::size_of::() - 4usize]; + ["Alignment of my_struct2"][::std::mem::align_of::() - 4usize]; +}; +impl my_struct2 { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_int { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/tests/expectations/tests/fit-macro-constant-types-signed.rs b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs similarity index 92% rename from tests/expectations/tests/fit-macro-constant-types-signed.rs rename to bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs index ccb76b8507..d4ad5e0fcc 100644 --- a/tests/expectations/tests/fit-macro-constant-types-signed.rs +++ b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const N0: i8 = 0; pub const N1: i8 = 1; pub const N2: i8 = 2; @@ -36,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, @@ -46,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/tests/expectations/tests/fit-macro-constant-types.rs b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs similarity index 92% rename from tests/expectations/tests/fit-macro-constant-types.rs rename to bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs index d8d3f207c1..5542a645da 100644 --- a/tests/expectations/tests/fit-macro-constant-types.rs +++ b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const N0: u8 = 0; pub const N1: u8 = 1; pub const N2: u8 = 2; @@ -36,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, @@ -46,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/flexarray.rs b/bindgen-tests/tests/expectations/tests/flexarray.rs new file mode 100644 index 0000000000..b9c800366e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/flexarray.rs @@ -0,0 +1,555 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#![feature(ptr_metadata, layout_for_ptr)] +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub const 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)] +#[derive(Debug, Default)] +pub struct flexarray { + pub count: ::std::os::raw::c_int, + pub data: FAM, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of flexarray"][::std::mem::size_of::() - 4usize]; + ["Alignment of flexarray"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: flexarray::count", + ][::std::mem::offset_of!(flexarray, count) - 0usize]; + [ + "Offset of field: flexarray::data", + ][::std::mem::offset_of!(flexarray, data) - 4usize]; +}; +impl flexarray<[::std::os::raw::c_int]> { + pub fn layout(len: usize) -> ::std::alloc::Layout { + unsafe { + let p: *const Self = ::std::ptr::from_raw_parts( + ::std::ptr::null::<()>(), + len, + ); + ::std::alloc::Layout::for_value_raw(p) + } + } + #[inline] + pub fn fixed(&self) -> (&flexarray<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + (&*(ptr as *const flexarray<[::std::os::raw::c_int; 0]>), len) + } + } + #[inline] + pub fn fixed_mut(&mut self) -> (&mut flexarray<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + (&mut *(ptr as *mut flexarray<[::std::os::raw::c_int; 0]>), len) + } + } +} +impl flexarray<[::std::os::raw::c_int; 0]> { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref(&self, len: usize) -> &flexarray<[::std::os::raw::c_int]> { + Self::flex_ptr(self, len) + } + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut( + &mut self, + len: usize, + ) -> &mut flexarray<[::std::os::raw::c_int]> { + Self::flex_ptr_mut(self, len).assume_init() + } + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>( + ptr: *const Self, + len: usize, + ) -> &'unbounded flexarray<[::std::os::raw::c_int]> { + &*::std::ptr::from_raw_parts(ptr as *const (), len) + } + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::std::mem::MaybeUninit<&'unbounded mut flexarray<[::std::os::raw::c_int]>> { + let mut uninit = ::std::mem::MaybeUninit::< + &mut flexarray<[::std::os::raw::c_int]>, + >::uninit(); + (uninit.as_mut_ptr() as *mut *mut flexarray<[::std::os::raw::c_int]>) + .write(::std::ptr::from_raw_parts_mut(ptr as *mut (), len)); + uninit + } +} +#[repr(C)] +#[derive(Debug, Default)] +pub struct flexarray_zero { + pub count: ::std::os::raw::c_int, + pub data: FAM, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of flexarray_zero"][::std::mem::size_of::() - 4usize]; + ["Alignment of flexarray_zero"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: flexarray_zero::count", + ][::std::mem::offset_of!(flexarray_zero, count) - 0usize]; + [ + "Offset of field: flexarray_zero::data", + ][::std::mem::offset_of!(flexarray_zero, data) - 4usize]; +}; +impl flexarray_zero<[::std::os::raw::c_int]> { + pub fn layout(len: usize) -> ::std::alloc::Layout { + unsafe { + let p: *const Self = ::std::ptr::from_raw_parts( + ::std::ptr::null::<()>(), + len, + ); + ::std::alloc::Layout::for_value_raw(p) + } + } + #[inline] + pub fn fixed(&self) -> (&flexarray_zero<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + (&*(ptr as *const flexarray_zero<[::std::os::raw::c_int; 0]>), len) + } + } + #[inline] + pub fn fixed_mut( + &mut self, + ) -> (&mut flexarray_zero<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + (&mut *(ptr as *mut flexarray_zero<[::std::os::raw::c_int; 0]>), len) + } + } +} +impl flexarray_zero<[::std::os::raw::c_int; 0]> { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref( + &self, + len: usize, + ) -> &flexarray_zero<[::std::os::raw::c_int]> { + Self::flex_ptr(self, len) + } + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut( + &mut self, + len: usize, + ) -> &mut flexarray_zero<[::std::os::raw::c_int]> { + Self::flex_ptr_mut(self, len).assume_init() + } + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>( + ptr: *const Self, + len: usize, + ) -> &'unbounded flexarray_zero<[::std::os::raw::c_int]> { + &*::std::ptr::from_raw_parts(ptr as *const (), len) + } + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::std::mem::MaybeUninit< + &'unbounded mut flexarray_zero<[::std::os::raw::c_int]>, + > { + let mut uninit = ::std::mem::MaybeUninit::< + &mut flexarray_zero<[::std::os::raw::c_int]>, + >::uninit(); + (uninit.as_mut_ptr() as *mut *mut flexarray_zero<[::std::os::raw::c_int]>) + .write(::std::ptr::from_raw_parts_mut(ptr as *mut (), len)); + uninit + } +} +#[repr(C)] +#[derive(Debug)] +pub struct flexarray_template { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub count: ::std::os::raw::c_int, + pub data: FAM, +} +impl flexarray_template { + pub fn layout(len: usize) -> ::std::alloc::Layout { + unsafe { + let p: *const Self = ::std::ptr::from_raw_parts( + ::std::ptr::null::<()>(), + len, + ); + ::std::alloc::Layout::for_value_raw(p) + } + } + #[inline] + pub fn fixed(&self) -> (&flexarray_template, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + (&*(ptr as *const flexarray_template), len) + } + } + #[inline] + pub fn fixed_mut(&mut self) -> (&mut flexarray_template, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + (&mut *(ptr as *mut flexarray_template), len) + } + } +} +impl flexarray_template { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref(&self, len: usize) -> &flexarray_template { + Self::flex_ptr(self, len) + } + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut( + &mut self, + len: usize, + ) -> &mut flexarray_template { + Self::flex_ptr_mut(self, len).assume_init() + } + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>( + ptr: *const Self, + len: usize, + ) -> &'unbounded flexarray_template { + &*::std::ptr::from_raw_parts(ptr as *const (), len) + } + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::std::mem::MaybeUninit<&'unbounded mut flexarray_template> { + let mut uninit = ::std::mem::MaybeUninit::< + &mut flexarray_template, + >::uninit(); + (uninit.as_mut_ptr() as *mut *mut flexarray_template) + .write(::std::ptr::from_raw_parts_mut(ptr as *mut (), len)); + uninit + } +} +impl Default for flexarray_template { + 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 flexarray_ref { + pub things: *mut flexarray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of flexarray_ref"][::std::mem::size_of::() - 8usize]; + ["Alignment of flexarray_ref"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: flexarray_ref::things", + ][::std::mem::offset_of!(flexarray_ref, things) - 0usize]; +}; +impl Default for flexarray_ref { + 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, Default)] +pub struct flexarray_bogus_zero_fam { + pub count: ::std::os::raw::c_int, + pub data1: __IncompleteArrayField<::std::os::raw::c_int>, + pub data2: FAM, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of flexarray_bogus_zero_fam", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of flexarray_bogus_zero_fam", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: flexarray_bogus_zero_fam::count", + ][::std::mem::offset_of!(flexarray_bogus_zero_fam, count) - 0usize]; + [ + "Offset of field: flexarray_bogus_zero_fam::data1", + ][::std::mem::offset_of!(flexarray_bogus_zero_fam, data1) - 4usize]; + [ + "Offset of field: flexarray_bogus_zero_fam::data2", + ][::std::mem::offset_of!(flexarray_bogus_zero_fam, data2) - 4usize]; +}; +impl flexarray_bogus_zero_fam<[::std::os::raw::c_char]> { + pub fn layout(len: usize) -> ::std::alloc::Layout { + unsafe { + let p: *const Self = ::std::ptr::from_raw_parts( + ::std::ptr::null::<()>(), + len, + ); + ::std::alloc::Layout::for_value_raw(p) + } + } + #[inline] + pub fn fixed( + &self, + ) -> (&flexarray_bogus_zero_fam<[::std::os::raw::c_char; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + ( + &*(ptr as *const flexarray_bogus_zero_fam<[::std::os::raw::c_char; 0]>), + len, + ) + } + } + #[inline] + pub fn fixed_mut( + &mut self, + ) -> (&mut flexarray_bogus_zero_fam<[::std::os::raw::c_char; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + ( + &mut *(ptr + as *mut flexarray_bogus_zero_fam<[::std::os::raw::c_char; 0]>), + len, + ) + } + } +} +impl flexarray_bogus_zero_fam<[::std::os::raw::c_char; 0]> { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref( + &self, + len: usize, + ) -> &flexarray_bogus_zero_fam<[::std::os::raw::c_char]> { + Self::flex_ptr(self, len) + } + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut( + &mut self, + len: usize, + ) -> &mut flexarray_bogus_zero_fam<[::std::os::raw::c_char]> { + Self::flex_ptr_mut(self, len).assume_init() + } + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>( + ptr: *const Self, + len: usize, + ) -> &'unbounded flexarray_bogus_zero_fam<[::std::os::raw::c_char]> { + &*::std::ptr::from_raw_parts(ptr as *const (), len) + } + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::std::mem::MaybeUninit< + &'unbounded mut flexarray_bogus_zero_fam<[::std::os::raw::c_char]>, + > { + let mut uninit = ::std::mem::MaybeUninit::< + &mut flexarray_bogus_zero_fam<[::std::os::raw::c_char]>, + >::uninit(); + (uninit.as_mut_ptr() + as *mut *mut flexarray_bogus_zero_fam<[::std::os::raw::c_char]>) + .write(::std::ptr::from_raw_parts_mut(ptr as *mut (), len)); + uninit + } +} +#[repr(C)] +#[repr(align(128))] +#[derive(Debug)] +pub struct flexarray_align { + pub count: ::std::os::raw::c_int, + pub data: FAM, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of flexarray_align"][::std::mem::size_of::() - 128usize]; + [ + "Alignment of flexarray_align", + ][::std::mem::align_of::() - 128usize]; + [ + "Offset of field: flexarray_align::count", + ][::std::mem::offset_of!(flexarray_align, count) - 0usize]; + [ + "Offset of field: flexarray_align::data", + ][::std::mem::offset_of!(flexarray_align, data) - 4usize]; +}; +impl flexarray_align<[::std::os::raw::c_int]> { + pub fn layout(len: usize) -> ::std::alloc::Layout { + unsafe { + let p: *const Self = ::std::ptr::from_raw_parts( + ::std::ptr::null::<()>(), + len, + ); + ::std::alloc::Layout::for_value_raw(p) + } + } + #[inline] + pub fn fixed(&self) -> (&flexarray_align<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + (&*(ptr as *const flexarray_align<[::std::os::raw::c_int; 0]>), len) + } + } + #[inline] + pub fn fixed_mut( + &mut self, + ) -> (&mut flexarray_align<[::std::os::raw::c_int; 0]>, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + (&mut *(ptr as *mut flexarray_align<[::std::os::raw::c_int; 0]>), len) + } + } +} +impl flexarray_align<[::std::os::raw::c_int; 0]> { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref( + &self, + len: usize, + ) -> &flexarray_align<[::std::os::raw::c_int]> { + Self::flex_ptr(self, len) + } + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut( + &mut self, + len: usize, + ) -> &mut flexarray_align<[::std::os::raw::c_int]> { + Self::flex_ptr_mut(self, len).assume_init() + } + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>( + ptr: *const Self, + len: usize, + ) -> &'unbounded flexarray_align<[::std::os::raw::c_int]> { + &*::std::ptr::from_raw_parts(ptr as *const (), len) + } + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::std::mem::MaybeUninit< + &'unbounded mut flexarray_align<[::std::os::raw::c_int]>, + > { + let mut uninit = ::std::mem::MaybeUninit::< + &mut flexarray_align<[::std::os::raw::c_int]>, + >::uninit(); + (uninit.as_mut_ptr() as *mut *mut flexarray_align<[::std::os::raw::c_int]>) + .write(::std::ptr::from_raw_parts_mut(ptr as *mut (), len)); + uninit + } +} +impl Default for flexarray_align<[::std::os::raw::c_int; 0]> { + 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/float128.rs b/bindgen-tests/tests/expectations/tests/float128.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/float128.rs @@ -0,0 +1 @@ +#![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/float16.rs b/bindgen-tests/tests/expectations/tests/float16.rs new file mode 100644 index 0000000000..2066b71801 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/float16.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] +#[repr(transparent)] +pub struct __BindgenFloat16(pub u16); +unsafe extern "C" { + pub static mut global: __BindgenFloat16; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct Test__Float16 { + pub f: __BindgenFloat16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test__Float16"][::std::mem::size_of::() - 2usize]; + ["Alignment of Test__Float16"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: Test__Float16::f", + ][::std::mem::offset_of!(Test__Float16, f) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Test__Float16Ref { + pub f: *mut __BindgenFloat16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test__Float16Ref"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of Test__Float16Ref", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: Test__Float16Ref::f", + ][::std::mem::offset_of!(Test__Float16Ref, f) - 0usize]; +}; +impl Default for Test__Float16Ref { + 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/forward-declaration-autoptr.rs b/bindgen-tests/tests/expectations/tests/forward-declaration-autoptr.rs new file mode 100644 index 0000000000..b74b408841 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/forward-declaration-autoptr.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct RefPtr { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_inner: *mut T, +} +impl Default for RefPtr { + 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 Bar { + pub m_member: RefPtr, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::m_member"][::std::mem::offset_of!(Bar, m_member) - 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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: RefPtr_open0_Foo_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: RefPtr_open0_Foo_close0", + ][::std::mem::align_of::>() - 8usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/forward-enum-decl.rs b/bindgen-tests/tests/expectations/tests/forward-enum-decl.rs new file mode 100644 index 0000000000..9949b39aae --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/forward-enum-decl.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum CSSPseudoClassType { + empty = 0, + link = 1, +} diff --git a/tests/expectations/tests/forward-inherit-struct-with-fields.rs b/bindgen-tests/tests/expectations/tests/forward-inherit-struct-with-fields.rs similarity index 89% rename from tests/expectations/tests/forward-inherit-struct-with-fields.rs rename to bindgen-tests/tests/expectations/tests/forward-inherit-struct-with-fields.rs index 330d766b31..069c76fead 100644 --- a/tests/expectations/tests/forward-inherit-struct-with-fields.rs +++ b/bindgen-tests/tests/expectations/tests/forward-inherit-struct-with-fields.rs @@ -1,16 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct js_RootedBase { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub foo: *mut T, pub next: *mut Rooted, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for js_RootedBase { fn default() -> Self { @@ -24,8 +18,8 @@ impl Default for js_RootedBase { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Rooted { - pub _base: js_RootedBase, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _base: js_RootedBase, } impl Default for Rooted { fn default() -> Self { diff --git a/tests/expectations/tests/forward-inherit-struct.rs b/bindgen-tests/tests/expectations/tests/forward-inherit-struct.rs similarity index 80% rename from tests/expectations/tests/forward-inherit-struct.rs rename to bindgen-tests/tests/expectations/tests/forward-inherit-struct.rs index 2c4546eb41..52888c4626 100644 --- a/tests/expectations/tests/forward-inherit-struct.rs +++ b/bindgen-tests/tests/expectations/tests/forward-inherit-struct.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct js_RootedBase { diff --git a/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs b/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs new file mode 100644 index 0000000000..79554d58e4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo_empty { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo_empty"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo_empty"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Bar { + pub f: *mut Foo, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::f"][::std::mem::offset_of!(Bar, f) - 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() + } + } +} +unsafe extern "C" { + #[link_name = "\u{1}_Z10baz_structP3Foo"] + pub fn baz_struct(f: *mut Foo); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Union { + _unused: [u8; 0], +} +unsafe extern "C" { + #[link_name = "\u{1}_Z9baz_unionP5Union"] + pub fn baz_union(u: *mut Union); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Quux { + _unused: [u8; 0], +} +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_opaque.rs b/bindgen-tests/tests/expectations/tests/forward_declared_opaque.rs new file mode 100644 index 0000000000..1f92194045 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/forward_declared_opaque.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct a { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct b { + _unused: [u8; 0], +} diff --git a/bindgen-tests/tests/expectations/tests/forward_declared_struct.rs b/bindgen-tests/tests/expectations/tests/forward_declared_struct.rs new file mode 100644 index 0000000000..1f6dfd0f58 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/forward_declared_struct.rs @@ -0,0 +1,23 @@ +#![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 b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of a"][::std::mem::size_of::
() - 4usize]; + ["Alignment of a"][::std::mem::align_of::() - 4usize]; + ["Offset of field: a::b"][::std::mem::offset_of!(a, b) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct c { + pub d: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of c"][::std::mem::size_of::() - 4usize]; + ["Alignment of c"][::std::mem::align_of::() - 4usize]; + ["Offset of field: c::d"][::std::mem::offset_of!(c, d) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/func_proto.rs b/bindgen-tests/tests/expectations/tests/func_proto.rs new file mode 100644 index 0000000000..496f595a0d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_proto.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type foo = ::std::option::Option< + unsafe extern "C" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int, +>; diff --git a/bindgen-tests/tests/expectations/tests/func_ptr.rs b/bindgen-tests/tests/expectations/tests/func_ptr.rs new file mode 100644 index 0000000000..b91bdba872 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_ptr.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub static mut foo: ::std::option::Option< + unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + >; +} diff --git a/bindgen-tests/tests/expectations/tests/func_ptr_in_struct.rs b/bindgen-tests/tests/expectations/tests/func_ptr_in_struct.rs new file mode 100644 index 0000000000..308bb069e0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_ptr_in_struct.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum baz { + __bindgen_cannot_repr_c_on_empty_enum = 0, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Foo { + pub bar: ::std::option::Option< + unsafe extern "C" fn(x: ::std::os::raw::c_int, y: ::std::os::raw::c_int) -> baz, + >, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs b/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs new file mode 100644 index 0000000000..504eefdfb1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn func() -> ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::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 new file mode 100644 index 0000000000..904c71cbe3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_return_must_use.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type MustUseInt = ::std::os::raw::c_int; +unsafe extern "C" { + #[must_use] + pub fn return_int() -> MustUseInt; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[must_use] +pub struct MustUseStruct { + _unused: [u8; 0], +} +unsafe extern "C" { + #[must_use] + pub fn return_struct() -> MustUseStruct; +} +///
+pub type AnnotatedInt = ::std::os::raw::c_int; +unsafe extern "C" { + #[must_use] + pub fn return_annotated_int() -> AnnotatedInt; +} +unsafe extern "C" { + pub fn return_plain_int() -> ::std::os::raw::c_int; +} +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +#[must_use] +pub struct AnnotatedStruct {} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AnnotatedStruct"][::std::mem::size_of::() - 0usize]; + ["Alignment of AnnotatedStruct"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[must_use] + pub fn return_annotated_struct() -> AnnotatedStruct; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct PlainStruct {} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PlainStruct"][::std::mem::size_of::() - 0usize]; + ["Alignment of PlainStruct"][::std::mem::align_of::() - 1usize]; +}; +///
+pub type TypedefPlainStruct = PlainStruct; +unsafe extern "C" { + pub fn return_plain_struct() -> PlainStruct; +} +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 new file mode 100644 index 0000000000..20bdc4ac27 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_with_array_arg.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..56cf40fb59 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/func_with_func_ptr_arg.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(bar: ::std::option::Option); +} +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), + >, + two: ::std::option::Option< + unsafe extern "C" fn(c: ::std::os::raw::c_int, d: ::std::os::raw::c_int), + >, + ); +} diff --git a/tests/expectations/tests/function-typedef-stdcall.rs b/bindgen-tests/tests/expectations/tests/function-typedef-stdcall.rs similarity index 77% rename from tests/expectations/tests/function-typedef-stdcall.rs rename to bindgen-tests/tests/expectations/tests/function-typedef-stdcall.rs index 11c9ef2072..3b08e0988c 100644 --- a/tests/expectations/tests/function-typedef-stdcall.rs +++ b/bindgen-tests/tests/expectations/tests/function-typedef-stdcall.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type PFN_VIGEM_X360_NOTIFICATION = ::std::option::Option< unsafe extern "C" fn( arg1: *mut ::std::os::raw::c_void, diff --git a/bindgen-tests/tests/expectations/tests/gen-constructors-neg.rs b/bindgen-tests/tests/expectations/tests/gen-constructors-neg.rs new file mode 100644 index 0000000000..551dff82cf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/gen-constructors-neg.rs @@ -0,0 +1,11 @@ +#![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]; +}; diff --git a/bindgen-tests/tests/expectations/tests/gen-constructors.rs b/bindgen-tests/tests/expectations/tests/gen-constructors.rs new file mode 100644 index 0000000000..80e6a25d70 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/gen-constructors.rs @@ -0,0 +1,23 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3FooC1Ei"] + pub fn Foo_Foo(this: *mut Foo, a: ::std::os::raw::c_int); +} +impl Foo { + #[inline] + pub unsafe fn new(a: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + Foo_Foo(__bindgen_tmp.as_mut_ptr(), a); + __bindgen_tmp.assume_init() + } +} diff --git a/bindgen-tests/tests/expectations/tests/gen-destructors-neg.rs b/bindgen-tests/tests/expectations/tests/gen-destructors-neg.rs new file mode 100644 index 0000000000..77b6a07bb1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/gen-destructors-neg.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct Foo { + pub bar: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/gen-destructors.rs b/bindgen-tests/tests/expectations/tests/gen-destructors.rs new file mode 100644 index 0000000000..c860c9985f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/gen-destructors.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct Foo { + pub bar: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3FooD1Ev"] + pub fn Foo_Foo_destructor(this: *mut Foo); +} +impl Foo { + #[inline] + pub unsafe fn destruct(&mut self) { + Foo_Foo_destructor(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/generate-inline.rs b/bindgen-tests/tests/expectations/tests/generate-inline.rs new file mode 100644 index 0000000000..c100f3936c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/generate-inline.rs @@ -0,0 +1,25 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo3barEv"] + pub fn Foo_bar() -> ::std::os::raw::c_int; +} +impl Foo { + #[inline] + pub unsafe fn bar() -> ::std::os::raw::c_int { + Foo_bar() + } +} +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/README.md b/bindgen-tests/tests/expectations/tests/generated/README.md new file mode 100644 index 0000000000..b4e8cabbf6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/generated/README.md @@ -0,0 +1,4 @@ +# Generated C, C++, Header files + +This directory contains files for features where extra files are generated +as a part of the feature. For example, `--wrap-static-fns`. diff --git a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c new file mode 100644 index 0000000000..a8fd5045d2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c @@ -0,0 +1,32 @@ +#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); } +void no_extra_argument__extern(__builtin_va_list va) { no_extra_argument(va); } +int many_va_list__extern(int i, __builtin_va_list va1, __builtin_va_list va2) { return many_va_list(i, va1, va2); } +int wrap_as_variadic_fn1__extern(int i, ...) { + int ret; + va_list ap; + + va_start(ap, i); + ret = wrap_as_variadic_fn1(i, ap); + va_end(ap); + return ret; +} +void wrap_as_variadic_fn2__extern(int i, ...) { + va_list ap; + + va_start(ap, i); + wrap_as_variadic_fn2(i, ap); + va_end(ap); +} 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 new file mode 100644 index 0000000000..e29db491fe --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/i128.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct foo { + pub my_signed: i128, + pub my_unsigned: u128, +} +#[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/in_class_typedef.rs b/bindgen-tests/tests/expectations/tests/in_class_typedef.rs new file mode 100644 index 0000000000..ccb73520d7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/in_class_typedef.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 Foo { + pub _address: u8, +} +pub type Foo_elem_type = T; +pub type Foo_ptr_type = *mut T; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo_Bar { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} diff --git a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs new file mode 100644 index 0000000000..a90fe54bf3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs @@ -0,0 +1,251 @@ +#![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(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub const 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)] +#[derive(Debug)] +pub struct foo { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub b: __IncompleteArrayField<*mut ::std::os::raw::c_void>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: foo::b"][::std::mem::offset_of!(foo, b) - 8usize]; +}; +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 a(&self) -> ::std::os::raw::c_char { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_char) { + 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) -> ::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]> { + 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 + } +} diff --git a/bindgen-tests/tests/expectations/tests/infinite-macro.rs b/bindgen-tests/tests/expectations/tests/infinite-macro.rs new file mode 100644 index 0000000000..cf2b32f0ed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/infinite-macro.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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/inherit-from-template-instantiation-with-vtable.rs b/bindgen-tests/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs new file mode 100644 index 0000000000..59e35f7b6c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs @@ -0,0 +1,169 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct BaseWithVtable__bindgen_vtable {} +/// This should have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BaseWithVtable { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub vtable_: *const BaseWithVtable__bindgen_vtable, + pub t: T, +} +impl Default for BaseWithVtable { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// This should not have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DerivedWithNoVirtualMethods { + pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of DerivedWithNoVirtualMethods", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of DerivedWithNoVirtualMethods", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for DerivedWithNoVirtualMethods { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// This should not have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DerivedWithVirtualMethods { + pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of DerivedWithVirtualMethods", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of DerivedWithVirtualMethods", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for DerivedWithVirtualMethods { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// This should not have any vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BaseWithoutVtable { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub u: U, +} +impl Default for BaseWithoutVtable { + 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 DerivedWithVtable__bindgen_vtable(::std::os::raw::c_void); +/// This should have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DerivedWithVtable { + pub vtable_: *const DerivedWithVtable__bindgen_vtable, + pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of DerivedWithVtable"][::std::mem::size_of::() - 16usize]; + [ + "Alignment of DerivedWithVtable", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for DerivedWithVtable { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// This should not have any vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DerivedWithoutVtable { + pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of DerivedWithoutVtable", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of DerivedWithoutVtable", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for DerivedWithoutVtable { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: BaseWithVtable_open0_ptr_char_close0", + ][::std::mem::size_of::>() - 16usize]; + [ + "Align of template specialization: BaseWithVtable_open0_ptr_char_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: BaseWithVtable_open0_ptr_char_close0", + ][::std::mem::size_of::>() - 16usize]; + [ + "Align of template specialization: BaseWithVtable_open0_ptr_char_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: BaseWithoutVtable_open0_ptr_char_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: BaseWithoutVtable_open0_ptr_char_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: BaseWithoutVtable_open0_ptr_char_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: BaseWithoutVtable_open0_ptr_char_close0", + ][::std::mem::align_of::>() - 8usize]; +}; diff --git a/tests/expectations/tests/inherit-namespaced.rs b/bindgen-tests/tests/expectations/tests/inherit-namespaced.rs similarity index 80% rename from tests/expectations/tests/inherit-namespaced.rs rename to bindgen-tests/tests/expectations/tests/inherit-namespaced.rs index 2c4546eb41..52888c4626 100644 --- a/tests/expectations/tests/inherit-namespaced.rs +++ b/bindgen-tests/tests/expectations/tests/inherit-namespaced.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct js_RootedBase { diff --git a/bindgen-tests/tests/expectations/tests/inherit_multiple_interfaces.rs b/bindgen-tests/tests/expectations/tests/inherit_multiple_interfaces.rs new file mode 100644 index 0000000000..da9e519156 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inherit_multiple_interfaces.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct A__bindgen_vtable {} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + pub vtable_: *const A__bindgen_vtable, + pub member: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::
() - 16usize]; + ["Alignment of A"][::std::mem::align_of::() - 8usize]; + ["Offset of field: A::member"][::std::mem::offset_of!(A, member) - 8usize]; +}; +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() + } + } +} +#[repr(C)] +pub struct B__bindgen_vtable {} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct B { + pub vtable_: *const B__bindgen_vtable, + pub member2: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 16usize]; + ["Alignment of B"][::std::mem::align_of::() - 8usize]; + ["Offset of field: B::member2"][::std::mem::offset_of!(B, member2) - 8usize]; +}; +impl Default for B { + 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 C { + pub _base: A, + pub _base_1: B, + pub member3: f32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 40usize]; + ["Alignment of C"][::std::mem::align_of::() - 8usize]; + ["Offset of field: C::member3"][::std::mem::offset_of!(C, member3) - 32usize]; +}; +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() + } + } +} diff --git a/tests/expectations/tests/inherit_named.rs b/bindgen-tests/tests/expectations/tests/inherit_named.rs similarity index 82% rename from tests/expectations/tests/inherit_named.rs rename to bindgen-tests/tests/expectations/tests/inherit_named.rs index a8eee20767..a371249ab0 100644 --- a/tests/expectations/tests/inherit_named.rs +++ b/bindgen-tests/tests/expectations/tests/inherit_named.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Wohoo { @@ -13,8 +7,8 @@ pub struct Wohoo { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Weeee { - pub _base: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _base: T, } impl Default for Weeee { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/inherit_typedef.rs b/bindgen-tests/tests/expectations/tests/inherit_typedef.rs new file mode 100644 index 0000000000..92320f45ef --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inherit_typedef.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 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]; +}; +pub type TypedefedFoo = Foo; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/inline-function.rs b/bindgen-tests/tests/expectations/tests/inline-function.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline-function.rs @@ -0,0 +1 @@ +#![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/inline_namespace.rs b/bindgen-tests/tests/expectations/tests/inline_namespace.rs new file mode 100644 index 0000000000..df05ab7b9d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline_namespace.rs @@ -0,0 +1,22 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + pub type Ty = ::std::os::raw::c_int; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar { + pub baz: root::foo::Ty, + } + #[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::baz"][::std::mem::offset_of!(Bar, baz) - 0usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/inline_namespace_allowlist.rs b/bindgen-tests/tests/expectations/tests/inline_namespace_allowlist.rs new file mode 100644 index 0000000000..915a40c654 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline_namespace_allowlist.rs @@ -0,0 +1,11 @@ +#![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 std { + #[allow(unused_imports)] + use self::super::super::root; + pub type string = *const ::std::os::raw::c_char; + } +} diff --git a/bindgen-tests/tests/expectations/tests/inline_namespace_conservative.rs b/bindgen-tests/tests/expectations/tests/inline_namespace_conservative.rs new file mode 100644 index 0000000000..6941e74adb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline_namespace_conservative.rs @@ -0,0 +1,27 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + pub mod bar { + #[allow(unused_imports)] + use self::super::super::super::root; + pub type Ty = ::std::os::raw::c_int; + } + pub type Ty = ::std::os::raw::c_longlong; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar { + pub baz: root::foo::bar::Ty, + } + #[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::baz"][::std::mem::offset_of!(Bar, baz) - 0usize]; + }; +} 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/inline_namespace_nested.rs b/bindgen-tests/tests/expectations/tests/inline_namespace_nested.rs new file mode 100644 index 0000000000..1474f47ba2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline_namespace_nested.rs @@ -0,0 +1,15 @@ +#![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 ranges { + #[allow(unused_imports)] + use self::super::super::root; + pub mod bar { + #[allow(unused_imports)] + use self::super::super::super::root; + pub const bar: ::std::os::raw::c_int = 0; + } + } +} diff --git a/tests/expectations/tests/inline_namespace_no_ns_enabled.rs b/bindgen-tests/tests/expectations/tests/inline_namespace_no_ns_enabled.rs similarity index 93% rename from tests/expectations/tests/inline_namespace_no_ns_enabled.rs rename to bindgen-tests/tests/expectations/tests/inline_namespace_no_ns_enabled.rs index 7a0c993555..66359bd51b 100644 --- a/tests/expectations/tests/inline_namespace_no_ns_enabled.rs +++ b/bindgen-tests/tests/expectations/tests/inline_namespace_no_ns_enabled.rs @@ -1,17 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug)] pub struct std_basic_string { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub hider: std_basic_string_Alloc_hider, pub length: ::std::os::raw::c_ulong, pub __bindgen_anon_1: std_basic_string__bindgen_ty_1, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -30,8 +24,8 @@ impl Default for std_basic_string_Alloc_hider { #[repr(C)] #[derive(Debug)] pub struct std_basic_string__bindgen_ty_1 { - pub inline_storage: [CharT; 4usize], pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub inline_storage: [CharT; 4usize], } impl Default for std_basic_string__bindgen_ty_1 { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs b/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs new file mode 100644 index 0000000000..16b1eb48ea --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs @@ -0,0 +1,31 @@ +#![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, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo_InnerType { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, +} +impl Default for Foo_InnerType { + 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 type Bar = InnerType; +unsafe extern "C" { + #[link_name = "\u{1}_Z4funcv"] + pub fn func() -> Bar; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct InnerType { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/inner_const.rs b/bindgen-tests/tests/expectations/tests/inner_const.rs new file mode 100644 index 0000000000..ad8af7ce35 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inner_const.rs @@ -0,0 +1,20 @@ +#![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 bar: ::std::os::raw::c_int, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo3BOOE"] + pub static mut Foo_BOO: ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo8whateverE"] + pub static mut Foo_whatever: Foo; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/inner_template_self.rs b/bindgen-tests/tests/expectations/tests/inner_template_self.rs new file mode 100644 index 0000000000..c8f9799be6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inner_template_self.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct LinkedList { + pub next: *mut LinkedList, + pub prev: *mut LinkedList, +} +impl Default for LinkedList { + 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 InstantiateIt { + pub m_list: LinkedList, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of InstantiateIt"][::std::mem::size_of::() - 16usize]; + ["Alignment of InstantiateIt"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: InstantiateIt::m_list", + ][::std::mem::offset_of!(InstantiateIt, m_list) - 0usize]; +}; +impl Default for InstantiateIt { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: LinkedList_open0_int_close0", + ][::std::mem::size_of::() - 16usize]; + [ + "Align of template specialization: LinkedList_open0_int_close0", + ][::std::mem::align_of::() - 8usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/int128_t.rs b/bindgen-tests/tests/expectations/tests/int128_t.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/int128_t.rs @@ -0,0 +1 @@ +#![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/issue-1025-unknown-enum-repr.rs b/bindgen-tests/tests/expectations/tests/issue-1025-unknown-enum-repr.rs new file mode 100644 index 0000000000..6e27b94ca9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1025-unknown-enum-repr.rs @@ -0,0 +1,7 @@ +#![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 type a__bindgen_ty_1 = i32; diff --git a/bindgen-tests/tests/expectations/tests/issue-1034.rs b/bindgen-tests/tests/expectations/tests/issue-1034.rs new file mode 100644 index 0000000000..90cc768a94 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1034.rs @@ -0,0 +1,164 @@ +#![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, Default, Copy, Clone)] +pub struct S2 { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S2"][::std::mem::size_of::() - 2usize]; + ["Alignment of S2"][::std::mem::align_of::() - 1usize]; +}; +impl S2 { + #[inline] + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-1040.rs b/bindgen-tests/tests/expectations/tests/issue-1040.rs new file mode 100644 index 0000000000..788c480424 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1040.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const g_107: ::std::os::raw::c_ulonglong = 18446744073709551615; 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 new file mode 100644 index 0000000000..50e9283b5a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs @@ -0,0 +1,164 @@ +#![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, Default, Copy, Clone)] +pub struct S1 { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S1"][::std::mem::size_of::() - 3usize]; + ["Alignment of S1"][::std::mem::align_of::() - 1usize]; +}; +impl S1 { + #[inline] + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + } +} diff --git a/tests/expectations/tests/issue-1113-template-references.rs b/bindgen-tests/tests/expectations/tests/issue-1113-template-references.rs similarity index 92% rename from tests/expectations/tests/issue-1113-template-references.rs rename to bindgen-tests/tests/expectations/tests/issue-1113-template-references.rs index c146583521..c0e76d8047 100644 --- a/tests/expectations/tests/issue-1113-template-references.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1113-template-references.rs @@ -1,17 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Entry { - pub _base: K, - pub mData: V, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _base: K, + pub mData: V, } impl Default for Entry { fn default() -> Self { @@ -31,10 +25,10 @@ pub type nsBaseHashtable_EntryType = Entry; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsBaseHashtable_EntryPtr { - pub mEntry: *mut nsBaseHashtable_EntryType, - pub mExistingEntry: bool, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub mEntry: *mut nsBaseHashtable_EntryType, + pub mExistingEntry: bool, } impl Default for nsBaseHashtable_EntryPtr { fn default() -> Self { 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 new file mode 100644 index 0000000000..7df1cdb741 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1118-using-forward-decl.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type c = nsTArray; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsTArray_base { + pub d: *mut ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsTArray_base"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsTArray_base"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: nsTArray_base::d", + ][::std::mem::offset_of!(nsTArray_base, d) - 0usize]; +}; +impl Default for nsTArray_base { + 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 nsTArray { + pub _base: nsTArray_base, +} +impl Default for nsTArray { + 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 nsIContent { + pub foo: nsTArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsIContent"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsIContent"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: nsIContent::foo", + ][::std::mem::offset_of!(nsIContent, foo) - 0usize]; +}; +impl Default for nsIContent { + 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}_Z35Gecko_GetAnonymousContentForElementv"] + pub fn Gecko_GetAnonymousContentForElement() -> *mut nsTArray; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: nsTArray_open0_ptr_nsIContent_close0", + ][::std::mem::size_of::() - 8usize]; + [ + "Align of template specialization: nsTArray_open0_ptr_nsIContent_close0", + ][::std::mem::align_of::() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: nsTArray_open0_ptr_nsIContent_close0", + ][::std::mem::size_of::() - 8usize]; + [ + "Align of template specialization: nsTArray_open0_ptr_nsIContent_close0", + ][::std::mem::align_of::() - 8usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs b/bindgen-tests/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs new file mode 100644 index 0000000000..10c769c38c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct Foo__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Debug)] +pub struct Foo { + pub vtable_: *const Foo__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; +}; +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() + } + } +} diff --git a/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs similarity index 91% rename from tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs rename to bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs index ed9f7c9ba8..5aaff691b4 100644 --- a/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs @@ -1,17 +1,7 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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 { @@ -45,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 new file mode 100644 index 0000000000..a69d005623 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs @@ -0,0 +1,17 @@ +#![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; + pub const D: Type = 1; +} 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 new file mode 100644 index 0000000000..a69d005623 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs @@ -0,0 +1,17 @@ +#![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; + pub const D: Type = 1; +} diff --git a/tests/expectations/tests/issue-1198-alias-rust-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-enum.rs similarity index 78% rename from tests/expectations/tests/issue-1198-alias-rust-enum.rs rename to bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-enum.rs index fda73a021f..f41d6e90ec 100644 --- a/tests/expectations/tests/issue-1198-alias-rust-enum.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-enum.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl MyDupeEnum { pub const A_alias: MyDupeEnum = MyDupeEnum::A; } diff --git a/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs b/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs new file mode 100644 index 0000000000..7c562437e4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn f(a: ::std::os::raw::c_int, ...); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub f: ::std::option::Option< + unsafe extern "C" fn( + p: *mut ::std::os::raw::c_void, + obj: *mut ::std::os::raw::c_void, + a: ::std::os::raw::c_int, + ... + ), + >, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Foo::f"][::std::mem::offset_of!(Foo, f) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1238-fwd-no-copy.rs b/bindgen-tests/tests/expectations/tests/issue-1238-fwd-no-copy.rs new file mode 100644 index 0000000000..81e8fed5f3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1238-fwd-no-copy.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug)] +pub struct MyType { + _unused: [u8; 0], +} +pub type MyTypeT = MyType; diff --git a/bindgen-tests/tests/expectations/tests/issue-1281.rs b/bindgen-tests/tests/expectations/tests/issue-1281.rs new file mode 100644 index 0000000000..03c80d21fb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1281.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar { + pub u: foo, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct foo { + pub foo: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::foo"][::std::mem::offset_of!(foo, foo) - 0usize]; +}; +#[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::u"][::std::mem::offset_of!(bar, u) - 0usize]; +}; +pub type bar_t = bar; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct baz { + pub f: foo, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of baz"][::std::mem::align_of::() - 4usize]; + ["Offset of field: baz::f"][::std::mem::offset_of!(baz, f) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1285.rs b/bindgen-tests/tests/expectations/tests/issue-1285.rs new file mode 100644 index 0000000000..6520163259 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1285.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-1291.rs b/bindgen-tests/tests/expectations/tests/issue-1291.rs new file mode 100644 index 0000000000..3c3fab3704 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1291.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct RTCRay { + pub org: [f32; 3usize], + pub align0: f32, + pub dir: [f32; 3usize], + pub align1: f32, + pub tnear: f32, + pub tfar: f32, + pub time: f32, + pub mask: ::std::os::raw::c_uint, + pub Ng: [f32; 3usize], + pub align2: f32, + pub u: f32, + pub v: f32, + pub geomID: ::std::os::raw::c_uint, + pub primID: ::std::os::raw::c_uint, + pub instID: ::std::os::raw::c_uint, +} +#[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", + ][::std::mem::offset_of!(RTCRay, align0) - 12usize]; + ["Offset of field: RTCRay::dir"][::std::mem::offset_of!(RTCRay, dir) - 16usize]; + [ + "Offset of field: RTCRay::align1", + ][::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", + ][::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", + ][::std::mem::offset_of!(RTCRay, geomID) - 72usize]; + [ + "Offset of field: RTCRay::primID", + ][::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 new file mode 100644 index 0000000000..c033570793 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1350-attribute-overloadable.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z11my_functioni"] + pub fn my_function(a: ::std::os::raw::c_int); +} +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 new file mode 100644 index 0000000000..f5e231ea96 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1375-prefixed-functions.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}my_custom_prefix_var_const_name"] + pub static var_const_name: ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "\u{1}my_custom_prefix_var_mut_name"] + pub static mut var_mut_name: ::std::os::raw::c_int; +} +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-1382-rust-primitive-types.rs b/bindgen-tests/tests/expectations/tests/issue-1382-rust-primitive-types.rs new file mode 100644 index 0000000000..277978d93c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1382-rust-primitive-types.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type i8_ = i8; +pub type u8_ = u8; +pub type i16_ = i16; +pub type u16_ = u16; +pub type i32_ = i32; +pub type u32_ = u32; +pub type i64_ = i64; +pub type u64_ = u64; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub i8_: ::std::os::raw::c_int, + pub u8_: ::std::os::raw::c_int, + pub i16_: ::std::os::raw::c_int, + pub u16_: ::std::os::raw::c_int, + pub i32_: ::std::os::raw::c_int, + pub u32_: ::std::os::raw::c_int, + pub i64_: ::std::os::raw::c_int, + pub u64_: ::std::os::raw::c_int, + pub i128_: ::std::os::raw::c_int, + pub u128_: ::std::os::raw::c_int, + pub isize_: ::std::os::raw::c_int, + pub usize_: ::std::os::raw::c_int, + pub f32_: ::std::os::raw::c_int, + pub f64_: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 56usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::i8_"][::std::mem::offset_of!(Foo, i8_) - 0usize]; + ["Offset of field: Foo::u8_"][::std::mem::offset_of!(Foo, u8_) - 4usize]; + ["Offset of field: Foo::i16_"][::std::mem::offset_of!(Foo, i16_) - 8usize]; + ["Offset of field: Foo::u16_"][::std::mem::offset_of!(Foo, u16_) - 12usize]; + ["Offset of field: Foo::i32_"][::std::mem::offset_of!(Foo, i32_) - 16usize]; + ["Offset of field: Foo::u32_"][::std::mem::offset_of!(Foo, u32_) - 20usize]; + ["Offset of field: Foo::i64_"][::std::mem::offset_of!(Foo, i64_) - 24usize]; + ["Offset of field: Foo::u64_"][::std::mem::offset_of!(Foo, u64_) - 28usize]; + ["Offset of field: Foo::i128_"][::std::mem::offset_of!(Foo, i128_) - 32usize]; + ["Offset of field: Foo::u128_"][::std::mem::offset_of!(Foo, u128_) - 36usize]; + ["Offset of field: Foo::isize_"][::std::mem::offset_of!(Foo, isize_) - 40usize]; + ["Offset of field: Foo::usize_"][::std::mem::offset_of!(Foo, usize_) - 44usize]; + ["Offset of field: Foo::f32_"][::std::mem::offset_of!(Foo, f32_) - 48usize]; + ["Offset of field: Foo::f64_"][::std::mem::offset_of!(Foo, f64_) - 52usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1435.rs b/bindgen-tests/tests/expectations/tests/issue-1435.rs new file mode 100644 index 0000000000..b50e1f88c0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1435.rs @@ -0,0 +1,18 @@ +#![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 ns { + #[allow(unused_imports)] + use self::super::super::root; + 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; + unsafe extern "C" { + #[link_name = "\u{1}_ZL2kA"] + pub static kA: root::AB; + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-1443.rs b/bindgen-tests/tests/expectations/tests/issue-1443.rs new file mode 100644 index 0000000000..ee1ffca8e5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1443.rs @@ -0,0 +1,94 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Bar { + pub f: *const Foo, + pub m: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 16usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::f"][::std::mem::offset_of!(Bar, f) - 0usize]; + ["Offset of field: Bar::m"][::std::mem::offset_of!(Bar, m) - 8usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Baz { + pub f: *mut Foo, + pub m: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 16usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Baz::f"][::std::mem::offset_of!(Baz, f) - 0usize]; + ["Offset of field: Baz::m"][::std::mem::offset_of!(Baz, m) - 8usize]; +}; +impl Default for Baz { + 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 Tar { + pub f: *const Foo, + pub m: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Tar"][::std::mem::size_of::() - 16usize]; + ["Alignment of Tar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Tar::f"][::std::mem::offset_of!(Tar, f) - 0usize]; + ["Offset of field: Tar::m"][::std::mem::offset_of!(Tar, m) - 8usize]; +}; +impl Default for Tar { + 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 Taz { + pub f: *mut Foo, + pub m: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Taz"][::std::mem::size_of::() - 16usize]; + ["Alignment of Taz"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Taz::f"][::std::mem::offset_of!(Taz, f) - 0usize]; + ["Offset of field: Taz::m"][::std::mem::offset_of!(Taz, m) - 8usize]; +}; +impl Default for Taz { + 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/issue-1454.rs b/bindgen-tests/tests/expectations/tests/issue-1454.rs new file mode 100644 index 0000000000..325ccfd977 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1454.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug)] +pub struct extern_type; +#[repr(C)] +#[derive(Debug)] +pub struct local_type { + pub inner: extern_type, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of local_type"][::std::mem::size_of::() - 0usize]; + ["Alignment of local_type"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: local_type::inner", + ][::std::mem::offset_of!(local_type, inner) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1464.rs b/bindgen-tests/tests/expectations/tests/issue-1464.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1464.rs @@ -0,0 +1 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] \ No newline at end of file diff --git a/tests/expectations/tests/issue-1488-enum-new-type.rs b/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs similarity index 88% rename from tests/expectations/tests/issue-1488-enum-new-type.rs rename to bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs index b762659a50..ab4b6fc971 100644 --- a/tests/expectations/tests/issue-1488-enum-new-type.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const Foo_A: Foo = 0; pub const Foo_B: Foo = 1; pub type Foo = ::std::os::raw::c_uint; @@ -12,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/tests/expectations/tests/issue-1488-options.rs b/bindgen-tests/tests/expectations/tests/issue-1488-options.rs similarity index 84% rename from tests/expectations/tests/issue-1488-options.rs rename to bindgen-tests/tests/expectations/tests/issue-1488-options.rs index cf13b56284..0f6efb93d4 100644 --- a/tests/expectations/tests/issue-1488-options.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1488-options.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type OSStatus = ::std::os::raw::c_int; #[repr(transparent)] #[derive(Debug, Copy, Clone)] diff --git a/bindgen-tests/tests/expectations/tests/issue-1488-template-alias-new-type.rs b/bindgen-tests/tests/expectations/tests/issue-1488-template-alias-new-type.rs new file mode 100644 index 0000000000..de43753e9c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1488-template-alias-new-type.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Wrapped(pub T); diff --git a/bindgen-tests/tests/expectations/tests/issue-1498.rs b/bindgen-tests/tests/expectations/tests/issue-1498.rs new file mode 100644 index 0000000000..286d2eb6ee --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1498.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C, packed)] +#[derive(Copy, Clone)] +pub struct rte_memseg { + ///< Start physical address. + pub phys_addr: u64, + pub __bindgen_anon_1: rte_memseg__bindgen_ty_1, + ///< Length of the segment. + pub len: usize, + ///< The pagesize of underlying memory + pub hugepage_sz: u64, + ///< NUMA socket ID. + pub socket_id: i32, + ///< Number of channels. + pub nchannel: u32, + ///< Number of ranks. + pub nrank: u32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rte_memseg__bindgen_ty_1 { + ///< Start virtual address. + pub addr: *mut ::std::os::raw::c_void, + ///< Makes sure addr is always 64 bits + pub addr_64: u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_memseg__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_memseg__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_memseg__bindgen_ty_1::addr", + ][::std::mem::offset_of!(rte_memseg__bindgen_ty_1, addr) - 0usize]; + [ + "Offset of field: rte_memseg__bindgen_ty_1::addr_64", + ][::std::mem::offset_of!(rte_memseg__bindgen_ty_1, addr_64) - 0usize]; +}; +impl Default for rte_memseg__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_memseg"][::std::mem::size_of::() - 44usize]; + ["Alignment of rte_memseg"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: rte_memseg::phys_addr", + ][::std::mem::offset_of!(rte_memseg, phys_addr) - 0usize]; + [ + "Offset of field: rte_memseg::len", + ][::std::mem::offset_of!(rte_memseg, len) - 16usize]; + [ + "Offset of field: rte_memseg::hugepage_sz", + ][::std::mem::offset_of!(rte_memseg, hugepage_sz) - 24usize]; + [ + "Offset of field: rte_memseg::socket_id", + ][::std::mem::offset_of!(rte_memseg, socket_id) - 32usize]; + [ + "Offset of field: rte_memseg::nchannel", + ][::std::mem::offset_of!(rte_memseg, nchannel) - 36usize]; + [ + "Offset of field: rte_memseg::nrank", + ][::std::mem::offset_of!(rte_memseg, nrank) - 40usize]; +}; +impl Default for rte_memseg { + 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/tests/expectations/tests/issue-1514.rs b/bindgen-tests/tests/expectations/tests/issue-1514.rs similarity index 90% rename from tests/expectations/tests/issue-1514.rs rename to bindgen-tests/tests/expectations/tests/issue-1514.rs index 31939ca588..aef63037ae 100644 --- a/tests/expectations/tests/issue-1514.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1514.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Thing { @@ -13,8 +7,8 @@ pub struct Thing { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Thing_Inner { - pub ptr: *mut T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: *mut T, } impl Default for Thing_Inner { fn default() -> Self { @@ -28,8 +22,8 @@ impl Default for Thing_Inner { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Thing_AnotherInner { - pub _base: Thing_Inner, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _base: Thing_Inner, } impl Default for Thing_AnotherInner { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/issue-1554.rs b/bindgen-tests/tests/expectations/tests/issue-1554.rs new file mode 100644 index 0000000000..7b1a2cd410 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1554.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#![feature(non_exhaustive)] +#[repr(u32)] +#[non_exhaustive] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Planet { + earth = 0, + mars = 1, +} diff --git a/bindgen-tests/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs new file mode 100644 index 0000000000..325ee4adc4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const a_b: a = 0; +pub const a_c: a = 1; +pub type a = ::std::os::raw::c_uint; +pub type d = u32; diff --git a/bindgen-tests/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs b/bindgen-tests/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs @@ -0,0 +1 @@ +#![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/issue-1947.rs b/bindgen-tests/tests/expectations/tests/issue-1947.rs new file mode 100644 index 0000000000..795b033a12 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -0,0 +1,641 @@ +#![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) }; + } + } +} +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 _bindgen_align: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub MADK: U8, + pub MABR: U8, + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 3usize]>, + pub _rB_: U8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of V56AMDY"][::std::mem::size_of::() - 8usize]; + ["Alignment of V56AMDY"][::std::mem::align_of::() - 2usize]; + ["Offset of field: V56AMDY::MADK"][::std::mem::offset_of!(V56AMDY, MADK) - 2usize]; + ["Offset of field: V56AMDY::MABR"][::std::mem::offset_of!(V56AMDY, MABR) - 3usize]; + ["Offset of field: V56AMDY::_rB_"][::std::mem::offset_of!(V56AMDY, _rB_) - 7usize]; +}; +impl V56AMDY { + #[inline] + pub fn MADZ(&self) -> U16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 10u8) as u16) } + } + #[inline] + pub fn set_MADZ(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 10u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MAI0(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 2u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MAI1(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 2u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MAI2(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 2u8, val as u64) + } + } + #[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, + MAI1: U16, + MAI2: U16, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 10u8, + { + let MADZ: u16 = unsafe { ::std::mem::transmute(MADZ) }; + MADZ as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 10usize, + 2u8, + { + let MAI0: u16 = unsafe { ::std::mem::transmute(MAI0) }; + MAI0 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 12usize, + 2u8, + { + let MAI1: u16 = unsafe { ::std::mem::transmute(MAI1) }; + MAI1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 2u8, + { + let MAI2: u16 = unsafe { ::std::mem::transmute(MAI2) }; + MAI2 as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub fn MATH(&self) -> U16 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 10u8) as u16) } + } + #[inline] + pub fn set_MATH(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 10u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MATE(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_2.set(10usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MATW(&mut self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_2.set(14usize, 2u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MASW(&mut self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(16usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MABW(&mut self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(20usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_MAXN(&mut self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(23usize, 1u8, val as u64) + } + } + #[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, + MATW: U16, + MASW: U8, + MABW: U8, + MAXN: U8, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 10u8, + { + let MATH: u16 = unsafe { ::std::mem::transmute(MATH) }; + MATH as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 10usize, + 4u8, + { + let MATE: u16 = unsafe { ::std::mem::transmute(MATE) }; + MATE as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 2u8, + { + let MATW: u16 = unsafe { ::std::mem::transmute(MATW) }; + MATW as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 4u8, + { + let MASW: u8 = unsafe { ::std::mem::transmute(MASW) }; + MASW as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 20usize, + 3u8, + { + let MABW: u8 = unsafe { ::std::mem::transmute(MABW) }; + MABW as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 23usize, + 1u8, + { + let MAXN: u8 = unsafe { ::std::mem::transmute(MAXN) }; + MAXN as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-1977-larger-arrays.rs b/bindgen-tests/tests/expectations/tests/issue-1977-larger-arrays.rs new file mode 100644 index 0000000000..df7a2192ed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1977-larger-arrays.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct S { + pub large_array: [::std::os::raw::c_char; 33usize], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct ST { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub large_array: [T; 33usize], +} +impl Default for ST { + 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/issue-1995.rs b/bindgen-tests/tests/expectations/tests/issue-1995.rs new file mode 100644 index 0000000000..0e36bdd9c9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-1995.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** This is a constant that has a docstring + + And expected to be found in generated bindings code too.*/ +pub const FOO: ::std::os::raw::c_int = 1; +/** This is a constant that has a docstring + + And expected to be found in generated bindings code too.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub baz: ::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::baz"][::std::mem::offset_of!(Bar, baz) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-2019.rs b/bindgen-tests/tests/expectations/tests/issue-2019.rs new file mode 100644 index 0000000000..4c91cf9972 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2019.rs @@ -0,0 +1,43 @@ +#![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 a: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 4usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::a"][::std::mem::offset_of!(A, a) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1A4makeEv"] + pub fn make() -> A; +} +impl A { + #[inline] + pub unsafe fn make() -> A { + make() + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 4usize]; + ["Alignment of B"][::std::mem::align_of::() - 4usize]; + ["Offset of field: B::b"][::std::mem::offset_of!(B, b) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1B4makeEv"] + pub fn make1() -> B; +} +impl B { + #[inline] + pub unsafe fn make() -> B { + make1() + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-2239-template-dependent-bit-width.rs b/bindgen-tests/tests/expectations/tests/issue-2239-template-dependent-bit-width.rs new file mode 100644 index 0000000000..6ff58b7559 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2239-template-dependent-bit-width.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct b { + pub _address: u8, +} +pub type b_td = a; +pub type b_ta = a; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct b_foo { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/issue-2556.rs b/bindgen-tests/tests/expectations/tests/issue-2556.rs new file mode 100644 index 0000000000..92fe5026b8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2556.rs @@ -0,0 +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 { + #[allow(unused_imports)] + use self::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct nsSize { + pub width: ::std::os::raw::c_int, + pub height: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of nsSize"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsSize"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: nsSize::width", + ][::std::mem::offset_of!(nsSize, width) - 0usize]; + [ + "Offset of field: nsSize::height", + ][::std::mem::offset_of!(nsSize, height) - 4usize]; + }; + pub mod foo { + #[allow(unused_imports)] + use self::super::super::root; + unsafe extern "C" { + #[link_name = "\u{1}_ZN3fooL22kFallbackIntrinsicSizeE"] + pub static kFallbackIntrinsicSize: root::nsSize; + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-2566-cstr.rs b/bindgen-tests/tests/expectations/tests/issue-2566-cstr.rs new file mode 100644 index 0000000000..4227cf2956 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2566-cstr.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO: &[u8; 4] = b"a\0b\0"; diff --git a/bindgen-tests/tests/expectations/tests/issue-2566.rs b/bindgen-tests/tests/expectations/tests/issue-2566.rs new file mode 100644 index 0000000000..4227cf2956 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2566.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO: &[u8; 4] = b"a\0b\0"; 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-2695.rs b/bindgen-tests/tests/expectations/tests/issue-2695.rs new file mode 100644 index 0000000000..20a016dbab --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2695.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C, packed(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test { + pub x: ::std::os::raw::c_ulong, + pub a: ::std::os::raw::c_char, + pub b: ::std::os::raw::c_char, + pub c: ::std::os::raw::c_char, + pub __bindgen_padding_0: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 12usize]; + ["Alignment of Test"][::std::mem::align_of::() - 2usize]; + ["Offset of field: Test::x"][::std::mem::offset_of!(Test, x) - 0usize]; + ["Offset of field: Test::a"][::std::mem::offset_of!(Test, a) - 8usize]; + ["Offset of field: Test::b"][::std::mem::offset_of!(Test, b) - 9usize]; + ["Offset of field: Test::c"][::std::mem::offset_of!(Test, c) - 10usize]; +}; 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/tests/expectations/tests/issue-358.rs b/bindgen-tests/tests/expectations/tests/issue-358.rs similarity index 86% rename from tests/expectations/tests/issue-358.rs rename to bindgen-tests/tests/expectations/tests/issue-358.rs index e9ee0f502f..ff915e9fba 100644 --- a/tests/expectations/tests/issue-358.rs +++ b/bindgen-tests/tests/expectations/tests/issue-358.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct JS_PersistentRooted { diff --git a/bindgen-tests/tests/expectations/tests/issue-372.rs b/bindgen-tests/tests/expectations/tests/issue-372.rs new file mode 100644 index 0000000000..cf00a70743 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-372.rs @@ -0,0 +1,85 @@ +#![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)] + #[derive(Debug, Copy, Clone)] + pub struct i { + pub j: *mut root::i, + pub k: *mut root::i, + pub l: bool, + } + #[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct d { + pub m: root::i, + } + #[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } + } + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum n { + o = 0, + p = 1, + q = 2, + r = 3, + s = 4, + t = 5, + b = 6, + ae = 7, + e = 8, + ag = 9, + ah = 10, + ai = 11, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct F { + 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 new file mode 100644 index 0000000000..cda9b6e338 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-410.rs @@ -0,0 +1,35 @@ +#![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 JS { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Value { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Value"][::std::mem::size_of::() - 1usize]; + ["Alignment of Value"][::std::mem::align_of::() - 1usize]; + }; + unsafe extern "C" { + #[link_name = "\u{1}_ZN2JS5Value1aE10JSWhyMagic"] + pub fn Value_a(this: *mut root::JS::Value, arg1: root::JSWhyMagic); + } + impl Value { + #[inline] + pub unsafe fn a(&mut self, arg1: root::JSWhyMagic) { + Value_a(self, arg1) + } + } + } + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum JSWhyMagic { + __bindgen_cannot_repr_c_on_empty_enum = 0, + } +} diff --git a/tests/expectations/tests/issue-446.rs b/bindgen-tests/tests/expectations/tests/issue-446.rs similarity index 86% rename from tests/expectations/tests/issue-446.rs rename to bindgen-tests/tests/expectations/tests/issue-446.rs index db69f159c7..5d625cb311 100644 --- a/tests/expectations/tests/issue-446.rs +++ b/bindgen-tests/tests/expectations/tests/issue-446.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct List { diff --git a/bindgen-tests/tests/expectations/tests/issue-447.rs b/bindgen-tests/tests/expectations/tests/issue-447.rs new file mode 100644 index 0000000000..8867a359a2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-447.rs @@ -0,0 +1,57 @@ +#![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 mozilla { + #[allow(unused_imports)] + use self::super::super::root; + pub mod detail { + #[allow(unused_imports)] + use self::super::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct GuardObjectNotifier { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of GuardObjectNotifier", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of GuardObjectNotifier", + ][::std::mem::align_of::() - 1usize]; + }; + } + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct JSAutoCompartment { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of JSAutoCompartment", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of JSAutoCompartment", + ][::std::mem::align_of::() - 1usize]; + }; + unsafe extern "C" { + #[link_name = "\u{1}_ZN17JSAutoCompartmentC1EN7mozilla6detail19GuardObjectNotifierE"] + pub fn JSAutoCompartment_JSAutoCompartment( + this: *mut root::JSAutoCompartment, + arg1: root::mozilla::detail::GuardObjectNotifier, + ); + } + impl JSAutoCompartment { + #[inline] + pub unsafe fn new(arg1: root::mozilla::detail::GuardObjectNotifier) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + JSAutoCompartment_JSAutoCompartment(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } + } +} diff --git a/tests/expectations/tests/issue-493.rs b/bindgen-tests/tests/expectations/tests/issue-493.rs similarity index 93% rename from tests/expectations/tests/issue-493.rs rename to bindgen-tests/tests/expectations/tests/issue-493.rs index 61c7f7929e..d2e4ea5375 100644 --- a/tests/expectations/tests/issue-493.rs +++ b/bindgen-tests/tests/expectations/tests/issue-493.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -30,7 +24,7 @@ impl ::std::default::Default for __BindgenUnionField { impl ::std::clone::Clone for __BindgenUnionField { #[inline] fn clone(&self) -> Self { - Self::new() + *self } } impl ::std::marker::Copy for __BindgenUnionField {} @@ -72,8 +66,7 @@ impl Default for basic_string___long { } } } -pub const basic_string___min_cap: basic_string__bindgen_ty_1 = - basic_string__bindgen_ty_1::__min_cap; +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 { @@ -123,8 +116,7 @@ impl Default for basic_string___ulx { } } } -pub const basic_string___n_words: basic_string__bindgen_ty_2 = - basic_string__bindgen_ty_2::__n_words; +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 { diff --git a/bindgen-tests/tests/expectations/tests/issue-511.rs b/bindgen-tests/tests/expectations/tests/issue-511.rs new file mode 100644 index 0000000000..9d26b334c3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-511.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub static mut a: *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub static mut b: *const ::std::os::raw::c_char; +} +unsafe extern "C" { + pub static c: *mut ::std::os::raw::c_char; +} +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 new file mode 100644 index 0000000000..881cb9c8ed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-537-repr-packed-n.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +/** This should not be opaque; we can see the attributes and can pack the + struct.*/ +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AlignedToOne { + pub i: ::std::os::raw::c_int, +} +#[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, +} +#[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.*/ +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct PackedToOne { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[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)] +pub struct PackedToTwo { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[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-537.rs b/bindgen-tests/tests/expectations/tests/issue-537.rs new file mode 100644 index 0000000000..d630b9ea4c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-537.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** This should not be opaque; we can see the attributes and can pack the + struct.*/ +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AlignedToOne { + pub i: ::std::os::raw::c_int, +} +#[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 opaque because although we can see the attributes, Rust before + 1.33 doesn't have `#[repr(packed(N))]`.*/ +#[repr(C, packed(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct AlignedToTwo { + pub i: ::std::os::raw::c_int, +} +#[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.*/ +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct PackedToOne { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[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]; +}; +/** In this case, even if we can detect the weird alignment triggered by + `#pragma pack(2)`, we can't do anything about it because Rust before 1.33 + doesn't have `#[repr(packed(N))]`. Therefore, we must make it opaque.*/ +#[repr(C, packed(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct PackedToTwo { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[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 new file mode 100644 index 0000000000..a160d0275d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce-2.rs @@ -0,0 +1,25 @@ +#![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 = __BindgenOpaqueArray<[u8; 0usize]>; +pub type Foo_SecondAlias = Foo; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce.rs b/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce.rs new file mode 100644 index 0000000000..b9c42ae12a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce.rs @@ -0,0 +1,6 @@ +#![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, +} diff --git a/bindgen-tests/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs b/bindgen-tests/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs new file mode 100644 index 0000000000..567325b82d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const ENUM_VARIANT_1: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_1; +pub const ENUM_VARIANT_2: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_2; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + ENUM_VARIANT_1 = 0, + ENUM_VARIANT_2 = 1, +} +pub type JS_Alias = u8; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct JS_Base { + pub f: JS_Alias, +} +impl Default for JS_Base { + 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 JS_AutoIdVector { + pub _base: JS_Base, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of JS_AutoIdVector"][::std::mem::size_of::() - 1usize]; + ["Alignment of JS_AutoIdVector"][::std::mem::align_of::() - 1usize]; +}; +impl Default for JS_AutoIdVector { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: JS_Base_open0_int_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: JS_Base_open0_int_close0", + ][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-573-layout-test-failures.rs b/bindgen-tests/tests/expectations/tests/issue-573-layout-test-failures.rs new file mode 100644 index 0000000000..aa5f457792 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-573-layout-test-failures.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Outer { + pub i: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct AutoIdVector { + pub ar: Outer, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AutoIdVector"][::std::mem::size_of::() - 1usize]; + ["Alignment of AutoIdVector"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: AutoIdVector::ar", + ][::std::mem::offset_of!(AutoIdVector, ar) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Outer_open0_int_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: Outer_open0_int_close0", + ][::std::mem::align_of::() - 1usize]; +}; 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 new file mode 100644 index 0000000000..9968501397 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs @@ -0,0 +1,31 @@ +#![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, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct _bindgen_ty_1 { + pub ar: a, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 1usize]; + ["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 1usize]; + [ + "Offset of field: _bindgen_ty_1::ar", + ][::std::mem::offset_of!(_bindgen_ty_1, ar) - 0usize]; +}; +unsafe extern "C" { + pub static mut AutoIdVector: _bindgen_ty_1; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: a_open0_int_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: a_open0_int_close0", + ][::std::mem::align_of::() - 1usize]; +}; 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 new file mode 100644 index 0000000000..2a85837e3d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type RefPtr = T; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub _address: u8, +} +pub type A_a = b; +#[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)] +pub struct e { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub d: RefPtr, +} +impl Default for e { + 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, Default, Copy, Clone)] +pub struct f { + pub _address: u8, +} +#[repr(C)] +pub struct g { + pub h: f, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of g"][::std::mem::size_of::() - 1usize]; + ["Alignment of g"][::std::mem::align_of::() - 1usize]; + ["Offset of field: g::h"][::std::mem::offset_of!(g, h) - 0usize]; +}; +impl Default for g { + 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 b { + pub _base: g, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of b"][::std::mem::size_of::() - 1usize]; + ["Alignment of b"][::std::mem::align_of::() - 1usize]; +}; +impl Default for b { + 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}_Z25Servo_Element_GetSnapshotv"] + pub fn Servo_Element_GetSnapshot() -> A; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: f_open0_e_open1_int_close1_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: f_open0_e_open1_int_close1_close0", + ][::std::mem::align_of::() - 1usize]; +}; diff --git a/tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs b/bindgen-tests/tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs similarity index 90% rename from tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs rename to bindgen-tests/tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs index ba886f361e..db94687737 100644 --- a/tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs +++ b/bindgen-tests/tests/expectations/tests/issue-638-stylo-cannot-find-T-in-this-scope.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct RefPtr { - pub use_of_t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub use_of_t: T, } impl Default for RefPtr { fn default() -> Self { @@ -23,8 +17,8 @@ impl Default for RefPtr { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesRefPtrWithAliasedTypeParam { - pub member: RefPtr>, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: RefPtr>, } pub type UsesRefPtrWithAliasedTypeParam_V = U; impl Default for UsesRefPtrWithAliasedTypeParam { diff --git a/bindgen-tests/tests/expectations/tests/issue-639-typedef-anon-field.rs b/bindgen-tests/tests/expectations/tests/issue-639-typedef-anon-field.rs new file mode 100644 index 0000000000..e940db1103 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-639-typedef-anon-field.rs @@ -0,0 +1,44 @@ +#![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 bar: Foo_Bar, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo_Bar { + pub abc: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo_Bar"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo_Bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo_Bar::abc"][::std::mem::offset_of!(Foo_Bar, abc) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz_Bar { + pub abc: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz_Bar"][::std::mem::size_of::() - 4usize]; + ["Alignment of Baz_Bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Baz_Bar::abc"][::std::mem::offset_of!(Baz_Bar, abc) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 1usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-643-inner-struct.rs b/bindgen-tests/tests/expectations/tests/issue-643-inner-struct.rs new file mode 100644 index 0000000000..0012c8f6aa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-643-inner-struct.rs @@ -0,0 +1,94 @@ +#![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 const 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)] +#[derive(Debug)] +pub struct rte_ring { + pub memzone: *mut rte_memzone, + pub prod: rte_ring_prod, + pub cons: rte_ring_cons, + pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct rte_ring_prod { + pub watermark: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ring_prod"][::std::mem::size_of::() - 4usize]; + ["Alignment of rte_ring_prod"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ring_prod::watermark", + ][::std::mem::offset_of!(rte_ring_prod, watermark) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct rte_ring_cons { + pub sc_dequeue: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ring_cons"][::std::mem::size_of::() - 4usize]; + ["Alignment of rte_ring_cons"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_ring_cons::sc_dequeue", + ][::std::mem::offset_of!(rte_ring_cons, sc_dequeue) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ring"][::std::mem::size_of::() - 16usize]; + ["Alignment of rte_ring"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_ring::memzone", + ][::std::mem::offset_of!(rte_ring, memzone) - 0usize]; + ["Offset of field: rte_ring::prod"][::std::mem::offset_of!(rte_ring, prod) - 8usize]; + [ + "Offset of field: rte_ring::cons", + ][::std::mem::offset_of!(rte_ring, cons) - 12usize]; + [ + "Offset of field: rte_ring::ring", + ][::std::mem::offset_of!(rte_ring, ring) - 16usize]; +}; +impl Default for rte_ring { + 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, Default, Copy, Clone)] +pub struct rte_memzone { + pub _address: u8, +} diff --git a/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs b/bindgen-tests/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs similarity index 83% rename from tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs rename to bindgen-tests/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs index 75d6581e2d..82e2ab4c42 100644 --- a/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs +++ b/bindgen-tests/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs @@ -1,17 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[derive(Clone, Copy, Debug)] pub struct RefPtr(T); - #[repr(C)] pub struct HasRefPtr { - pub refptr_member: RefPtr>, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub refptr_member: RefPtr>, } pub type HasRefPtr_TypedefOfT = T; impl Default for HasRefPtr { 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 new file mode 100644 index 0000000000..5d87159f97 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-648-derive-debug-with-padding.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** We emit a `[u8; 63usize]` padding field for this struct, which cannot derive + Debug/Hash because 63 is over the hard coded limit.*/ +#[repr(C)] +#[repr(align(64))] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct NoDebug { + pub c: ::std::os::raw::c_char, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/** 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(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ShouldDeriveDebugButDoesNot { + pub c: [::std::os::raw::c_char; 32usize], + pub d: ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ShouldDeriveDebugButDoesNot", + ][::std::mem::size_of::() - 64usize]; + [ + "Alignment of ShouldDeriveDebugButDoesNot", + ][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: ShouldDeriveDebugButDoesNot::c", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} 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 new file mode 100644 index 0000000000..6bf02be74e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-654-struct-fn-collision.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + _unused: [u8; 0], +} +unsafe extern "C" { + pub fn foo() -> ::std::os::raw::c_int; +} diff --git a/tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs b/bindgen-tests/tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs similarity index 92% rename from tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs rename to bindgen-tests/tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs index 5636a977b4..2e68628323 100644 --- a/tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs +++ b/bindgen-tests/tests/expectations/tests/issue-662-cannot-find-T-in-this-scope.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct RefPtr { - pub a: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub a: T, } impl Default for RefPtr { fn default() -> Self { @@ -23,8 +17,8 @@ impl Default for RefPtr { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsMainThreadPtrHolder { - pub a: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub a: T, } impl Default for nsMainThreadPtrHolder { fn default() -> Self { @@ -38,8 +32,8 @@ impl Default for nsMainThreadPtrHolder { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsMainThreadPtrHandle { - pub mPtr: RefPtr>, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub mPtr: RefPtr>, } impl Default for nsMainThreadPtrHandle { fn default() -> Self { diff --git a/tests/expectations/tests/issue-662-part-2.rs b/bindgen-tests/tests/expectations/tests/issue-662-part-2.rs similarity index 89% rename from tests/expectations/tests/issue-662-part-2.rs rename to bindgen-tests/tests/expectations/tests/issue-662-part-2.rs index e8d14bfe89..9ddcdc5e8d 100644 --- a/tests/expectations/tests/issue-662-part-2.rs +++ b/bindgen-tests/tests/expectations/tests/issue-662-part-2.rs @@ -1,18 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[derive(Clone, Copy, Debug)] pub struct RefPtr(T); - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsMainThreadPtrHolder { - pub a: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub a: T, } impl Default for nsMainThreadPtrHolder { fn default() -> Self { @@ -25,8 +18,8 @@ impl Default for nsMainThreadPtrHolder { } #[repr(C)] pub struct nsMainThreadPtrHandle { - pub mPtr: RefPtr>, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub mPtr: RefPtr>, } impl Default for nsMainThreadPtrHandle { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/issue-674-1.rs b/bindgen-tests/tests/expectations/tests/issue-674-1.rs new file mode 100644 index 0000000000..1a3dce44d0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-674-1.rs @@ -0,0 +1,33 @@ +#![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 mozilla { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Maybe { + pub _address: u8, + } + pub type Maybe_ValueType = T; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct CapturingContentInfo { + pub a: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of CapturingContentInfo", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of CapturingContentInfo", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: CapturingContentInfo::a", + ][::std::mem::offset_of!(CapturingContentInfo, a) - 0usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/issue-674-2.rs b/bindgen-tests/tests/expectations/tests/issue-674-2.rs new file mode 100644 index 0000000000..980928fe97 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-674-2.rs @@ -0,0 +1,52 @@ +#![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 JS { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Rooted { + pub _address: u8, + } + pub type Rooted_ElementType = T; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct c { + pub b: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of c"][::std::mem::size_of::() - 1usize]; + ["Alignment of c"][::std::mem::align_of::() - 1usize]; + ["Offset of field: c::b"][::std::mem::offset_of!(c, b) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct B { + pub a: root::c, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of B"][::std::mem::size_of::() - 1usize]; + ["Alignment of B"][::std::mem::align_of::() - 1usize]; + ["Offset of field: B::a"][::std::mem::offset_of!(B, a) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct StaticRefPtr { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of template specialization: StaticRefPtr_open0_B_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: StaticRefPtr_open0_B_close0", + ][::std::mem::align_of::() - 1usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/issue-674-3.rs b/bindgen-tests/tests/expectations/tests/issue-674-3.rs new file mode 100644 index 0000000000..4e2f26a46f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-674-3.rs @@ -0,0 +1,36 @@ +#![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 nsRefPtrHashtable { + pub _address: u8, + } + pub type nsRefPtrHashtable_UserDataType = *mut PtrType; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct a { + pub b: 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]; + ["Offset of field: a::b"][::std::mem::offset_of!(a, b) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct nsCSSValue { + pub c: root::a, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of nsCSSValue"][::std::mem::size_of::() - 1usize]; + ["Alignment of nsCSSValue"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: nsCSSValue::c", + ][::std::mem::offset_of!(nsCSSValue, c) - 0usize]; + }; +} diff --git a/tests/expectations/tests/issue-677-nested-ns-specifier.rs b/bindgen-tests/tests/expectations/tests/issue-677-nested-ns-specifier.rs similarity index 79% rename from tests/expectations/tests/issue-677-nested-ns-specifier.rs rename to bindgen-tests/tests/expectations/tests/issue-677-nested-ns-specifier.rs index 800f0dc84b..34ec99688a 100644 --- a/tests/expectations/tests/issue-677-nested-ns-specifier.rs +++ b/bindgen-tests/tests/expectations/tests/issue-677-nested-ns-specifier.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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)] diff --git a/bindgen-tests/tests/expectations/tests/issue-691-template-parameter-virtual.rs b/bindgen-tests/tests/expectations/tests/issue-691-template-parameter-virtual.rs new file mode 100644 index 0000000000..1313d61168 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-691-template-parameter-virtual.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct VirtualMethods__bindgen_vtable {} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct VirtualMethods { + pub vtable_: *const VirtualMethods__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of VirtualMethods"][::std::mem::size_of::() - 8usize]; + ["Alignment of VirtualMethods"][::std::mem::align_of::() - 8usize]; +}; +impl Default for VirtualMethods { + 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, Default, Copy, Clone)] +pub struct Set { + pub bar: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ServoElementSnapshotTable { + pub _base: Set, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ServoElementSnapshotTable", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of ServoElementSnapshotTable", + ][::std::mem::align_of::() - 4usize]; +}; +impl Default for ServoElementSnapshotTable { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Set_open0_VirtualMethods_close0", + ][::std::mem::size_of::() - 4usize]; + [ + "Align of template specialization: Set_open0_VirtualMethods_close0", + ][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-710-must-use-type.rs b/bindgen-tests/tests/expectations/tests/issue-710-must-use-type.rs new file mode 100644 index 0000000000..d7006dd011 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-710-must-use-type.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[must_use] +pub struct A { + _unused: [u8; 0], +} +///
+#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[must_use] +pub struct B { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct C { + _unused: [u8; 0], +} 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 new file mode 100644 index 0000000000..bc1951e7d1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs @@ -0,0 +1,351 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(target_os = "windows"))] +#[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, Default, Copy, Clone)] +pub struct Foo { + pub _bindgen_align: [u64; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 32usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 32usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; +}; +impl Foo { + #[inline] + pub fn m_bitfield(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 64u8) as u64) } + } + #[inline] + pub fn set_m_bitfield(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 64u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_m_bar(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(64usize, 64u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_foo(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(128usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bar(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(192usize, 64u8, val as u64) + } + } + #[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, + foo: ::std::os::raw::c_ulong, + bar: ::std::os::raw::c_ulong, + ) -> __BindgenBitfieldUnit<[u8; 32usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 32usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 64u8, + { + let m_bitfield: u64 = unsafe { ::std::mem::transmute(m_bitfield) }; + m_bitfield as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 64usize, + 64u8, + { + let m_bar: u64 = unsafe { ::std::mem::transmute(m_bar) }; + m_bar as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 128usize, + 1u8, + { + let foo: u64 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 192usize, + 64u8, + { + let bar: u64 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }, + ); + __bindgen_bitfield_unit + } +} 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-753.rs b/bindgen-tests/tests/expectations/tests/issue-753.rs new file mode 100644 index 0000000000..3119ec569e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-753.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const CONST: u32 = 5; +pub const OTHER_CONST: u32 = 6; +pub const LARGE_CONST: u32 = 1536; diff --git a/bindgen-tests/tests/expectations/tests/issue-769-bad-instantiation-test.rs b/bindgen-tests/tests/expectations/tests/issue-769-bad-instantiation-test.rs new file mode 100644 index 0000000000..59a1d9afa3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-769-bad-instantiation-test.rs @@ -0,0 +1,40 @@ +#![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, Copy, Clone)] + pub struct Rooted { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, + } + impl Default for Rooted { + 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 type AutoValueVector_Alias = ::std::os::raw::c_int; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of template specialization: Rooted_open0_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: Rooted_open0_int_close0", + ][::std::mem::align_of::>() - 4usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of template specialization: Rooted_open0_AutoValueVector_Alias_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: Rooted_open0_AutoValueVector_Alias_close0", + ][::std::mem::align_of::>() - 4usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs new file mode 100644 index 0000000000..90eb048640 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + _unused: [u8; 0], +} +#[repr(C)] +#[repr(align(1))] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct B { + pub _bindgen_opaque_blob: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 1usize]; + ["Alignment of B"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1B1aE"] + pub static mut B_a: A; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct C { + pub b: B, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 1usize]; + ["Alignment of C"][::std::mem::align_of::() - 1usize]; + ["Offset of field: C::b"][::std::mem::offset_of!(C, b) - 0usize]; +}; 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 new file mode 100644 index 0000000000..3d3ee5e590 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Pupper { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Pupper"][::std::mem::size_of::() - 1usize]; + ["Alignment of Pupper"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Doggo { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Doggo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Doggo"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct SuchWow { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of SuchWow"][::std::mem::size_of::() - 1usize]; + ["Alignment of SuchWow"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[repr(align(1))] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Opaque { + pub _bindgen_opaque_blob: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Opaque"][::std::mem::size_of::() - 1usize]; + ["Alignment of Opaque"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN6Opaque17eleven_out_of_tenEv"] + pub fn Opaque_eleven_out_of_ten(this: *mut Opaque) -> SuchWow; +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN6OpaqueC1E6Pupper"] + pub fn Opaque_Opaque(this: *mut Opaque, pup: Pupper); +} +impl Opaque { + #[inline] + pub unsafe fn eleven_out_of_ten(&mut self) -> SuchWow { + Opaque_eleven_out_of_ten(self) + } + #[inline] + pub unsafe fn new(pup: Pupper) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + Opaque_Opaque(__bindgen_tmp.as_mut_ptr(), pup); + __bindgen_tmp.assume_init() + } +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN6Opaque11MAJESTIC_AFE"] + pub static mut Opaque_MAJESTIC_AF: Doggo; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Allowlisted { + pub some_member: Opaque, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Allowlisted"][::std::mem::size_of::() - 1usize]; + ["Alignment of Allowlisted"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: Allowlisted::some_member", + ][::std::mem::offset_of!(Allowlisted, some_member) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-816.rs b/bindgen-tests/tests/expectations/tests/issue-816.rs new file mode 100644 index 0000000000..b1494afede --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-816.rs @@ -0,0 +1,2052 @@ +#![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, Default, Copy, Clone)] +pub struct capabilities { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of capabilities"][::std::mem::size_of::() - 16usize]; + ["Alignment of capabilities"][::std::mem::align_of::() - 4usize]; +}; +impl capabilities { + #[inline] + pub fn bit_1(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bit_1(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_2(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_3(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_4(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_5(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_6(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_7(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_8(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_9(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_10(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_11(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_12(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_13(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_14(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_15(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_16(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_17(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_18(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_19(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_20(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_21(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_22(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_23(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_24(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_25(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_26(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_27(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_28(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(27usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_29(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(28usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_30(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(29usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_31(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(30usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_32(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_33(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_34(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(33usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_35(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(34usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_36(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(35usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_37(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(36usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_38(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(37usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_39(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(38usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_40(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(39usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_bit_41(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(40usize, 1u8, val as u64) + } + } + #[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, + bit_3: ::std::os::raw::c_uint, + bit_4: ::std::os::raw::c_uint, + bit_5: ::std::os::raw::c_uint, + bit_6: ::std::os::raw::c_uint, + bit_7: ::std::os::raw::c_uint, + bit_8: ::std::os::raw::c_uint, + bit_9: ::std::os::raw::c_uint, + bit_10: ::std::os::raw::c_uint, + bit_11: ::std::os::raw::c_uint, + bit_12: ::std::os::raw::c_uint, + bit_13: ::std::os::raw::c_uint, + bit_14: ::std::os::raw::c_uint, + bit_15: ::std::os::raw::c_uint, + bit_16: ::std::os::raw::c_uint, + bit_17: ::std::os::raw::c_uint, + bit_18: ::std::os::raw::c_uint, + bit_19: ::std::os::raw::c_uint, + bit_20: ::std::os::raw::c_uint, + bit_21: ::std::os::raw::c_uint, + bit_22: ::std::os::raw::c_uint, + bit_23: ::std::os::raw::c_uint, + bit_24: ::std::os::raw::c_uint, + bit_25: ::std::os::raw::c_uint, + bit_26: ::std::os::raw::c_uint, + bit_27: ::std::os::raw::c_uint, + bit_28: ::std::os::raw::c_uint, + bit_29: ::std::os::raw::c_uint, + bit_30: ::std::os::raw::c_uint, + bit_31: ::std::os::raw::c_uint, + bit_32: ::std::os::raw::c_uint, + bit_33: ::std::os::raw::c_uint, + bit_34: ::std::os::raw::c_uint, + bit_35: ::std::os::raw::c_uint, + bit_36: ::std::os::raw::c_uint, + bit_37: ::std::os::raw::c_uint, + bit_38: ::std::os::raw::c_uint, + bit_39: ::std::os::raw::c_uint, + bit_40: ::std::os::raw::c_uint, + bit_41: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 16usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let bit_1: u32 = unsafe { ::std::mem::transmute(bit_1) }; + bit_1 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let bit_2: u32 = unsafe { ::std::mem::transmute(bit_2) }; + bit_2 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let bit_3: u32 = unsafe { ::std::mem::transmute(bit_3) }; + bit_3 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 1u8, + { + let bit_4: u32 = unsafe { ::std::mem::transmute(bit_4) }; + bit_4 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 1u8, + { + let bit_5: u32 = unsafe { ::std::mem::transmute(bit_5) }; + bit_5 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 5usize, + 1u8, + { + let bit_6: u32 = unsafe { ::std::mem::transmute(bit_6) }; + bit_6 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 6usize, + 1u8, + { + let bit_7: u32 = unsafe { ::std::mem::transmute(bit_7) }; + bit_7 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 7usize, + 1u8, + { + let bit_8: u32 = unsafe { ::std::mem::transmute(bit_8) }; + bit_8 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 1u8, + { + let bit_9: u32 = unsafe { ::std::mem::transmute(bit_9) }; + bit_9 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 1u8, + { + let bit_10: u32 = unsafe { ::std::mem::transmute(bit_10) }; + bit_10 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 10usize, + 1u8, + { + let bit_11: u32 = unsafe { ::std::mem::transmute(bit_11) }; + bit_11 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 11usize, + 1u8, + { + let bit_12: u32 = unsafe { ::std::mem::transmute(bit_12) }; + bit_12 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 12usize, + 1u8, + { + let bit_13: u32 = unsafe { ::std::mem::transmute(bit_13) }; + bit_13 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 13usize, + 1u8, + { + let bit_14: u32 = unsafe { ::std::mem::transmute(bit_14) }; + bit_14 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 1u8, + { + let bit_15: u32 = unsafe { ::std::mem::transmute(bit_15) }; + bit_15 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 15usize, + 1u8, + { + let bit_16: u32 = unsafe { ::std::mem::transmute(bit_16) }; + bit_16 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 1u8, + { + let bit_17: u32 = unsafe { ::std::mem::transmute(bit_17) }; + bit_17 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 17usize, + 1u8, + { + let bit_18: u32 = unsafe { ::std::mem::transmute(bit_18) }; + bit_18 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 18usize, + 1u8, + { + let bit_19: u32 = unsafe { ::std::mem::transmute(bit_19) }; + bit_19 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 19usize, + 1u8, + { + let bit_20: u32 = unsafe { ::std::mem::transmute(bit_20) }; + bit_20 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 20usize, + 1u8, + { + let bit_21: u32 = unsafe { ::std::mem::transmute(bit_21) }; + bit_21 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 21usize, + 1u8, + { + let bit_22: u32 = unsafe { ::std::mem::transmute(bit_22) }; + bit_22 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 22usize, + 1u8, + { + let bit_23: u32 = unsafe { ::std::mem::transmute(bit_23) }; + bit_23 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 23usize, + 1u8, + { + let bit_24: u32 = unsafe { ::std::mem::transmute(bit_24) }; + bit_24 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 24usize, + 1u8, + { + let bit_25: u32 = unsafe { ::std::mem::transmute(bit_25) }; + bit_25 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 25usize, + 1u8, + { + let bit_26: u32 = unsafe { ::std::mem::transmute(bit_26) }; + bit_26 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 26usize, + 1u8, + { + let bit_27: u32 = unsafe { ::std::mem::transmute(bit_27) }; + bit_27 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 27usize, + 1u8, + { + let bit_28: u32 = unsafe { ::std::mem::transmute(bit_28) }; + bit_28 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 28usize, + 1u8, + { + let bit_29: u32 = unsafe { ::std::mem::transmute(bit_29) }; + bit_29 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 29usize, + 1u8, + { + let bit_30: u32 = unsafe { ::std::mem::transmute(bit_30) }; + bit_30 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 30usize, + 1u8, + { + let bit_31: u32 = unsafe { ::std::mem::transmute(bit_31) }; + bit_31 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 31usize, + 1u8, + { + let bit_32: u32 = unsafe { ::std::mem::transmute(bit_32) }; + bit_32 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 32usize, + 1u8, + { + let bit_33: u32 = unsafe { ::std::mem::transmute(bit_33) }; + bit_33 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 33usize, + 1u8, + { + let bit_34: u32 = unsafe { ::std::mem::transmute(bit_34) }; + bit_34 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 34usize, + 1u8, + { + let bit_35: u32 = unsafe { ::std::mem::transmute(bit_35) }; + bit_35 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 35usize, + 1u8, + { + let bit_36: u32 = unsafe { ::std::mem::transmute(bit_36) }; + bit_36 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 36usize, + 1u8, + { + let bit_37: u32 = unsafe { ::std::mem::transmute(bit_37) }; + bit_37 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 37usize, + 1u8, + { + let bit_38: u32 = unsafe { ::std::mem::transmute(bit_38) }; + bit_38 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 38usize, + 1u8, + { + let bit_39: u32 = unsafe { ::std::mem::transmute(bit_39) }; + bit_39 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 39usize, + 1u8, + { + let bit_40: u32 = unsafe { ::std::mem::transmute(bit_40) }; + bit_40 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 40usize, + 1u8, + { + let bit_41: u32 = unsafe { ::std::mem::transmute(bit_41) }; + bit_41 as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs b/bindgen-tests/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs new file mode 100644 index 0000000000..a367e2e0e1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type Foo_self_type = u8; diff --git a/bindgen-tests/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.rs b/bindgen-tests/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.rs new file mode 100644 index 0000000000..551dff82cf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.rs @@ -0,0 +1,11 @@ +#![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]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-833-1.rs b/bindgen-tests/tests/expectations/tests/issue-833-1.rs new file mode 100644 index 0000000000..5aa8c3078b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-833-1.rs @@ -0,0 +1,8 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct nsTArray { + pub hdr: *const (), +} +unsafe extern "C" { + pub fn func() -> *mut nsTArray; +} diff --git a/bindgen-tests/tests/expectations/tests/issue-833-2.rs b/bindgen-tests/tests/expectations/tests/issue-833-2.rs new file mode 100644 index 0000000000..b8ef2f8554 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-833-2.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct nsTArray { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/issue-833.rs b/bindgen-tests/tests/expectations/tests/issue-833.rs new file mode 100644 index 0000000000..9698fdb479 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-833.rs @@ -0,0 +1,8 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct nsTArray { + pub hdr: *const T, +} +unsafe extern "C" { + pub fn func() -> *mut nsTArray<::std::os::raw::c_int>; +} diff --git a/bindgen-tests/tests/expectations/tests/issue-834.rs b/bindgen-tests/tests/expectations/tests/issue-834.rs new file mode 100644 index 0000000000..4119a450e0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-834.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct U { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of U"][::std::mem::size_of::() - 1usize]; + ["Alignment of U"][::std::mem::align_of::() - 1usize]; +}; 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 new file mode 100644 index 0000000000..6beeae69d8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-848-replacement-system-include.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** This is intended to replace another type, but won't if we treat this include + as a system include, because clang doesn't parse comments there. + + See #848. + +
*/ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsTArray { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m: *mut T, +} +impl Default for nsTArray { + 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" { + 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 new file mode 100644 index 0000000000..023c8695e3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-888-enum-var-decl-jump.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 { + #[allow(unused_imports)] + use self::super::root; + pub mod Halide { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Type { + pub _address: u8, + } + unsafe extern "C" { + #[link_name = "\u{1}_ZN6Halide4Type1bE"] + pub static mut Type_b: root::a; + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Type"][::std::mem::size_of::() - 1usize]; + ["Alignment of Type"][::std::mem::align_of::() - 1usize]; + }; + } + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum a { + __bindgen_cannot_repr_c_on_empty_enum = 0, + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs b/bindgen-tests/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs new file mode 100644 index 0000000000..5e8dde04e3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct BlocklistMe(u8); +/// Because this type contains a blocklisted type, it should not derive Copy. +#[repr(C)] +pub struct ShouldNotBeCopy { + pub a: BlocklistMe, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ShouldNotBeCopy"][::std::mem::size_of::() - 1usize]; + ["Alignment of ShouldNotBeCopy"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ShouldNotBeCopy::a", + ][::std::mem::offset_of!(ShouldNotBeCopy, a) - 0usize]; +}; +impl Default for ShouldNotBeCopy { + 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/issue-946.rs b/bindgen-tests/tests/expectations/tests/issue-946.rs new file mode 100644 index 0000000000..bdd56c0326 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-946.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct foo {} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 0usize]; + ["Alignment of foo"][::std::mem::align_of::() - 1usize]; +}; +pub type bar = foo; diff --git a/bindgen-tests/tests/expectations/tests/issue_311.rs b/bindgen-tests/tests/expectations/tests/issue_311.rs new file mode 100644 index 0000000000..2e0114e43e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue_311.rs @@ -0,0 +1,30 @@ +#![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 jsval_layout { + pub __bindgen_anon_1: root::jsval_layout__bindgen_ty_1, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct jsval_layout__bindgen_ty_1 { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of jsval_layout__bindgen_ty_1", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of jsval_layout__bindgen_ty_1", + ][::std::mem::align_of::() - 1usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of jsval_layout"][::std::mem::size_of::() - 1usize]; + ["Alignment of jsval_layout"][::std::mem::align_of::() - 1usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/issue_315.rs b/bindgen-tests/tests/expectations/tests/issue_315.rs new file mode 100644 index 0000000000..cecdccc2aa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue_315.rs @@ -0,0 +1,3 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+pub type c
= a; diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs new file mode 100644 index 0000000000..dc0ef8ed7f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -0,0 +1,483 @@ +#![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) }; + } + } +} +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(Copy, Clone)] +pub union jsval_layout { + pub asBits: u64, + pub debugView: jsval_layout__bindgen_ty_1, + pub s: jsval_layout__bindgen_ty_2, + pub asDouble: f64, + pub asPtr: *mut ::std::os::raw::c_void, + pub asWord: usize, + pub asUIntPtr: usize, +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct jsval_layout__bindgen_ty_1 { + pub _bindgen_align: [u64; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of jsval_layout__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of jsval_layout__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for jsval_layout__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 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 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) } + } + #[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 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, + ) -> __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(Copy, Clone)] +pub struct jsval_layout__bindgen_ty_2 { + pub payload: jsval_layout__bindgen_ty_2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union jsval_layout__bindgen_ty_2__bindgen_ty_1 { + pub i32_: i32, + pub u32_: u32, + pub why: JSWhyMagic, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of jsval_layout__bindgen_ty_2__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of jsval_layout__bindgen_ty_2__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::i32_", + ][::std::mem::offset_of!(jsval_layout__bindgen_ty_2__bindgen_ty_1, i32_) - 0usize]; + [ + "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::u32_", + ][::std::mem::offset_of!(jsval_layout__bindgen_ty_2__bindgen_ty_1, u32_) - 0usize]; + [ + "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::why", + ][::std::mem::offset_of!(jsval_layout__bindgen_ty_2__bindgen_ty_1, why) - 0usize]; +}; +impl Default for jsval_layout__bindgen_ty_2__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of jsval_layout__bindgen_ty_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of jsval_layout__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: jsval_layout__bindgen_ty_2::payload", + ][::std::mem::offset_of!(jsval_layout__bindgen_ty_2, payload) - 0usize]; +}; +impl Default for jsval_layout__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of jsval_layout"][::std::mem::size_of::() - 8usize]; + ["Alignment of jsval_layout"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: jsval_layout::asBits", + ][::std::mem::offset_of!(jsval_layout, asBits) - 0usize]; + [ + "Offset of field: jsval_layout::debugView", + ][::std::mem::offset_of!(jsval_layout, debugView) - 0usize]; + [ + "Offset of field: jsval_layout::s", + ][::std::mem::offset_of!(jsval_layout, s) - 0usize]; + [ + "Offset of field: jsval_layout::asDouble", + ][::std::mem::offset_of!(jsval_layout, asDouble) - 0usize]; + [ + "Offset of field: jsval_layout::asPtr", + ][::std::mem::offset_of!(jsval_layout, asPtr) - 0usize]; + [ + "Offset of field: jsval_layout::asWord", + ][::std::mem::offset_of!(jsval_layout, asWord) - 0usize]; + [ + "Offset of field: jsval_layout::asUIntPtr", + ][::std::mem::offset_of!(jsval_layout, asUIntPtr) - 0usize]; +}; +impl Default for jsval_layout { + 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(Copy, Clone)] +pub struct Value { + pub data: jsval_layout, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Value"][::std::mem::size_of::() - 8usize]; + ["Alignment of Value"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Value::data"][::std::mem::offset_of!(Value, data) - 0usize]; +}; +impl Default for Value { + 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/tests/expectations/tests/keywords.rs b/bindgen-tests/tests/expectations/tests/keywords.rs similarity index 75% rename from tests/expectations/tests/keywords.rs rename to bindgen-tests/tests/expectations/tests/keywords.rs index 055b0f003e..0a55ee0463 100644 --- a/tests/expectations/tests/keywords.rs +++ b/bindgen-tests/tests/expectations/tests/keywords.rs @@ -1,219 +1,225 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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; +} +unsafe extern "C" { + #[link_name = "\u{1}await"] + pub static mut await_: ::std::os::raw::c_int; +} +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 new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout.rs @@ -0,0 +1 @@ +#![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 new file mode 100644 index 0000000000..a942adb8f2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_align.rs @@ -0,0 +1,385 @@ +#![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(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub const 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)] +#[derive(Debug)] +pub struct rte_kni_fifo { + ///< Next position to be written + pub write: ::std::os::raw::c_uint, + ///< Next position to be read + pub read: ::std::os::raw::c_uint, + ///< Circular buffer length + pub len: ::std::os::raw::c_uint, + ///< Pointer size - for 32/64 bit OS + pub elem_size: ::std::os::raw::c_uint, + ///< The buffer contains mbuf pointers + pub buffer: __IncompleteArrayField<*mut ::std::os::raw::c_void>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_kni_fifo"][::std::mem::size_of::() - 16usize]; + ["Alignment of rte_kni_fifo"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_kni_fifo::write", + ][::std::mem::offset_of!(rte_kni_fifo, write) - 0usize]; + [ + "Offset of field: rte_kni_fifo::read", + ][::std::mem::offset_of!(rte_kni_fifo, read) - 4usize]; + [ + "Offset of field: rte_kni_fifo::len", + ][::std::mem::offset_of!(rte_kni_fifo, len) - 8usize]; + [ + "Offset of field: rte_kni_fifo::elem_size", + ][::std::mem::offset_of!(rte_kni_fifo, elem_size) - 12usize]; + [ + "Offset of field: rte_kni_fifo::buffer", + ][::std::mem::offset_of!(rte_kni_fifo, buffer) - 16usize]; +}; +impl Default for rte_kni_fifo { + 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, Default, Copy, Clone)] +pub struct rte_eth_link { + pub _bindgen_align: [u64; 0], + ///< ETH_SPEED_NUM_ + pub link_speed: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_link"][::std::mem::size_of::() - 8usize]; + ["Alignment of rte_eth_link"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_link::link_speed", + ][::std::mem::offset_of!(rte_eth_link, link_speed) - 0usize]; +}; +impl rte_eth_link { + #[inline] + pub fn link_duplex(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } + } + #[inline] + pub fn set_link_duplex(&mut self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_link_autoneg(&mut self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_link_status(&mut self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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, + link_status: u16, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let link_duplex: u16 = unsafe { ::std::mem::transmute(link_duplex) }; + link_duplex as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let link_autoneg: u16 = unsafe { + ::std::mem::transmute(link_autoneg) + }; + link_autoneg as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let link_status: u16 = unsafe { ::std::mem::transmute(link_status) }; + link_status as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/layout_arp.rs b/bindgen-tests/tests/expectations/tests/layout_arp.rs new file mode 100644 index 0000000000..c94dc2ce24 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_arp.rs @@ -0,0 +1,96 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const ETHER_ADDR_LEN: u32 = 6; +pub const ARP_HRD_ETHER: u32 = 1; +pub const ARP_OP_REQUEST: u32 = 1; +pub const ARP_OP_REPLY: u32 = 2; +pub const ARP_OP_REVREQUEST: u32 = 3; +pub const ARP_OP_REVREPLY: u32 = 4; +pub const ARP_OP_INVREQUEST: u32 = 8; +pub const ARP_OP_INVREPLY: u32 = 9; +/** Ethernet address: + A universally administered address is uniquely assigned to a device by its + manufacturer. The first three octets (in transmission order) contain the + Organizationally Unique Identifier (OUI). The following three (MAC-48 and + EUI-48) octets are assigned by that organization with the only constraint + of uniqueness. + A locally administered address is assigned to a device by a network + administrator and does not contain OUIs. + See http://standards.ieee.org/regauth/groupmac/tutorial.html*/ +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ether_addr { + ///< Addr bytes in tx order + pub addr_bytes: [u8; 6usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ether_addr"][::std::mem::size_of::() - 6usize]; + ["Alignment of ether_addr"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ether_addr::addr_bytes", + ][::std::mem::offset_of!(ether_addr, addr_bytes) - 0usize]; +}; +/// ARP header IPv4 payload. +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct arp_ipv4 { + ///< sender hardware address + pub arp_sha: ether_addr, + ///< sender IP address + pub arp_sip: u32, + ///< target hardware address + pub arp_tha: ether_addr, + ///< target IP address + pub arp_tip: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of arp_ipv4"][::std::mem::size_of::() - 20usize]; + ["Alignment of arp_ipv4"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: arp_ipv4::arp_sha", + ][::std::mem::offset_of!(arp_ipv4, arp_sha) - 0usize]; + [ + "Offset of field: arp_ipv4::arp_sip", + ][::std::mem::offset_of!(arp_ipv4, arp_sip) - 6usize]; + [ + "Offset of field: arp_ipv4::arp_tha", + ][::std::mem::offset_of!(arp_ipv4, arp_tha) - 10usize]; + [ + "Offset of field: arp_ipv4::arp_tip", + ][::std::mem::offset_of!(arp_ipv4, arp_tip) - 16usize]; +}; +/// ARP header. +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct arp_hdr { + pub arp_hrd: u16, + pub arp_pro: u16, + pub arp_hln: u8, + pub arp_pln: u8, + pub arp_op: u16, + pub arp_data: arp_ipv4, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of arp_hdr"][::std::mem::size_of::() - 28usize]; + ["Alignment of arp_hdr"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: arp_hdr::arp_hrd", + ][::std::mem::offset_of!(arp_hdr, arp_hrd) - 0usize]; + [ + "Offset of field: arp_hdr::arp_pro", + ][::std::mem::offset_of!(arp_hdr, arp_pro) - 2usize]; + [ + "Offset of field: arp_hdr::arp_hln", + ][::std::mem::offset_of!(arp_hdr, arp_hln) - 4usize]; + [ + "Offset of field: arp_hdr::arp_pln", + ][::std::mem::offset_of!(arp_hdr, arp_pln) - 5usize]; + [ + "Offset of field: arp_hdr::arp_op", + ][::std::mem::offset_of!(arp_hdr, arp_op) - 6usize]; + [ + "Offset of field: arp_hdr::arp_data", + ][::std::mem::offset_of!(arp_hdr, arp_data) - 8usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/layout_array.rs b/bindgen-tests/tests/expectations/tests/layout_array.rs new file mode 100644 index 0000000000..3afe1c2dd8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_array.rs @@ -0,0 +1,233 @@ +#![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; +pub const RTE_HEAP_NUM_FREELISTS: u32 = 13; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rte_mempool { + _unused: [u8; 0], +} +/** Prototype for implementation specific data provisioning function. + + The function should provide the implementation specific memory for + for use by the other mempool ops functions in a given mempool ops struct. + E.g. the default ops provides an instance of the rte_ring for this purpose. + it will most likely point to a different type of data structure, and + will be transparent to the application programmer. + This function should set mp->pool_data.*/ +pub type rte_mempool_alloc_t = ::std::option::Option< + unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int, +>; +/// Free the opaque private data pointed to by mp->pool_data pointer. +pub type rte_mempool_free_t = ::std::option::Option< + unsafe extern "C" fn(mp: *mut rte_mempool), +>; +/// Enqueue an object into the external pool. +pub type rte_mempool_enqueue_t = ::std::option::Option< + unsafe extern "C" fn( + mp: *mut rte_mempool, + obj_table: *const *mut ::std::os::raw::c_void, + n: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int, +>; +/// Dequeue an object from the external pool. +pub type rte_mempool_dequeue_t = ::std::option::Option< + unsafe extern "C" fn( + mp: *mut rte_mempool, + obj_table: *mut *mut ::std::os::raw::c_void, + n: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int, +>; +/// Return the number of available objects in the external pool. +pub type rte_mempool_get_count = ::std::option::Option< + unsafe extern "C" fn(mp: *const rte_mempool) -> ::std::os::raw::c_uint, +>; +/// Structure defining mempool operations structure +#[repr(C)] +#[repr(align(64))] +#[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], + ///< Allocate private data. + pub alloc: rte_mempool_alloc_t, + ///< Free the external pool. + pub free: rte_mempool_free_t, + ///< Enqueue an object. + pub enqueue: rte_mempool_enqueue_t, + ///< Dequeue an object. + pub dequeue: rte_mempool_dequeue_t, + ///< Get qty of available objs. + pub get_count: rte_mempool_get_count, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_mempool_ops"][::std::mem::size_of::() - 128usize]; + [ + "Alignment of rte_mempool_ops", + ][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: rte_mempool_ops::name", + ][::std::mem::offset_of!(rte_mempool_ops, name) - 0usize]; + [ + "Offset of field: rte_mempool_ops::alloc", + ][::std::mem::offset_of!(rte_mempool_ops, alloc) - 32usize]; + [ + "Offset of field: rte_mempool_ops::free", + ][::std::mem::offset_of!(rte_mempool_ops, free) - 40usize]; + [ + "Offset of field: rte_mempool_ops::enqueue", + ][::std::mem::offset_of!(rte_mempool_ops, enqueue) - 48usize]; + [ + "Offset of field: rte_mempool_ops::dequeue", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// The rte_spinlock_t type. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_spinlock_t { + ///< lock status 0 = unlocked, 1 = locked + pub locked: ::std::os::raw::c_int, +} +#[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 + the mempools can be shared across primary and secondary processes. + The indices used to access the array are valid across processes, whereas + any function pointers stored directly in the mempool struct would not be. + This results in us simply having "ops_index" in the mempool struct.*/ +#[repr(C)] +#[repr(align(64))] +#[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: __BindgenOpaqueArray8<[u8; 56usize]>, + /// Storage for all possible ops structs. + pub ops: [rte_mempool_ops; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mempool_ops_table", + ][::std::mem::size_of::() - 2112usize]; + [ + "Alignment of rte_mempool_ops_table", + ][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: rte_mempool_ops_table::sl", + ][::std::mem::offset_of!(rte_mempool_ops_table, sl) - 0usize]; + [ + "Offset of field: rte_mempool_ops_table::num_ops", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// Structure to hold malloc heap +#[repr(C)] +#[repr(align(64))] +#[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], + pub alloc_count: ::std::os::raw::c_uint, + pub total_size: usize, +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct malloc_heap__bindgen_ty_1 { + pub lh_first: *mut malloc_elem, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of malloc_heap__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of malloc_heap__bindgen_ty_1", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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", + ][::std::mem::offset_of!(malloc_heap, lock) - 0usize]; + [ + "Offset of field: malloc_heap::free_head", + ][::std::mem::offset_of!(malloc_heap, free_head) - 8usize]; + [ + "Offset of field: malloc_heap::alloc_count", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct malloc_elem { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs b/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs new file mode 100644 index 0000000000..315663e0fc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs @@ -0,0 +1,163 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const RTE_CACHE_LINE_SIZE: u32 = 64; +pub const RTE_LIBRTE_IP_FRAG_MAX_FRAG: u32 = 4; +pub const IP_LAST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_LAST_FRAG_IDX; +pub const IP_FIRST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_FIRST_FRAG_IDX; +pub const IP_MIN_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MIN_FRAG_NUM; +pub const IP_MAX_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MAX_FRAG_NUM; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + ///< index of last fragment + IP_LAST_FRAG_IDX = 0, + ///< index of first fragment + IP_FIRST_FRAG_IDX = 1, + ///< minimum number of fragments + IP_MIN_FRAG_NUM = 2, + IP_MAX_FRAG_NUM = 4, +} +/// @internal fragmented mbuf +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ip_frag { + ///< offset into the packet + pub ofs: u16, + ///< length of fragment + pub len: u16, + ///< fragment mbuf + pub mb: *mut rte_mbuf, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// @internal to uniquely indetify fragmented datagram. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ip_frag_key { + ///< src address, first 8 bytes used for IPv4 + pub src_dst: [u64; 4usize], + ///< dst address + pub id: u32, + ///< src/dst key length + pub key_len: u32, +} +#[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", + ][::std::mem::offset_of!(ip_frag_key, src_dst) - 0usize]; + [ + "Offset of field: ip_frag_key::id", + ][::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(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ip_frag_pkt { + ///< LRU list + pub lru: ip_frag_pkt__bindgen_ty_1, + ///< fragmentation key + pub key: ip_frag_key, + ///< creation timestamp + pub start: u64, + ///< expected reassembled size + pub total_size: u32, + ///< size of fragments received + pub frag_size: u32, + ///< index of next entry to fill + pub last_idx: u32, + ///< fragments + pub frags: [ip_frag; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ip_frag_pkt__bindgen_ty_1 { + pub tqe_next: *mut ip_frag_pkt, + pub tqe_prev: *mut *mut ip_frag_pkt, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ip_frag_pkt__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of ip_frag_pkt__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_next", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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", + ][::std::mem::offset_of!(ip_frag_pkt, lru) - 0usize]; + [ + "Offset of field: ip_frag_pkt::key", + ][::std::mem::offset_of!(ip_frag_pkt, key) - 16usize]; + [ + "Offset of field: ip_frag_pkt::start", + ][::std::mem::offset_of!(ip_frag_pkt, start) - 56usize]; + [ + "Offset of field: ip_frag_pkt::total_size", + ][::std::mem::offset_of!(ip_frag_pkt, total_size) - 64usize]; + [ + "Offset of field: ip_frag_pkt::frag_size", + ][::std::mem::offset_of!(ip_frag_pkt, frag_size) - 68usize]; + [ + "Offset of field: ip_frag_pkt::last_idx", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +///< fragment mbuf +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_mbuf { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/layout_cmdline_token.rs b/bindgen-tests/tests/expectations/tests/layout_cmdline_token.rs new file mode 100644 index 0000000000..fb7b3bf584 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_cmdline_token.rs @@ -0,0 +1,173 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** Stores a pointer to the ops struct, and the offset: the place to + write the parsed result in the destination structure.*/ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct cmdline_token_hdr { + pub ops: *mut cmdline_token_ops, + pub offset: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cmdline_token_hdr"][::std::mem::size_of::() - 16usize]; + [ + "Alignment of cmdline_token_hdr", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: cmdline_token_hdr::ops", + ][::std::mem::offset_of!(cmdline_token_hdr, ops) - 0usize]; + [ + "Offset of field: cmdline_token_hdr::offset", + ][::std::mem::offset_of!(cmdline_token_hdr, offset) - 8usize]; +}; +impl Default for cmdline_token_hdr { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/** Stores a pointer to the ops struct, and the offset: the place to + write the parsed result in the destination structure.*/ +pub type cmdline_parse_token_hdr_t = cmdline_token_hdr; +/** A token is defined by this structure. + + parse() takes the token as first argument, then the source buffer + starting at the token we want to parse. The 3rd arg is a pointer + where we store the parsed data (as binary). It returns the number of + parsed chars on success and a negative value on error. + + complete_get_nb() returns the number of possible values for this + token if completion is possible. If it is NULL or if it returns 0, + no completion is possible. + + complete_get_elt() copy in dstbuf (the size is specified in the + parameter) the i-th possible completion for this token. returns 0 + on success or and a negative value on error. + + get_help() fills the dstbuf with the help for the token. It returns + -1 on error and 0 on success.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct cmdline_token_ops { + /// parse(token ptr, buf, res pts, buf len) + pub parse: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut cmdline_parse_token_hdr_t, + arg2: *const ::std::os::raw::c_char, + arg3: *mut ::std::os::raw::c_void, + arg4: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int, + >, + /// return the num of possible choices for this token + pub complete_get_nb: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut cmdline_parse_token_hdr_t, + ) -> ::std::os::raw::c_int, + >, + /// return the elt x for this token (token, idx, dstbuf, size) + pub complete_get_elt: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut cmdline_parse_token_hdr_t, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_char, + arg4: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int, + >, + /// get help for this token (token, dstbuf, size) + pub get_help: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut cmdline_parse_token_hdr_t, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int, + >, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cmdline_token_ops"][::std::mem::size_of::() - 32usize]; + [ + "Alignment of cmdline_token_ops", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: cmdline_token_ops::parse", + ][::std::mem::offset_of!(cmdline_token_ops, parse) - 0usize]; + [ + "Offset of field: cmdline_token_ops::complete_get_nb", + ][::std::mem::offset_of!(cmdline_token_ops, complete_get_nb) - 8usize]; + [ + "Offset of field: cmdline_token_ops::complete_get_elt", + ][::std::mem::offset_of!(cmdline_token_ops, complete_get_elt) - 16usize]; + [ + "Offset of field: cmdline_token_ops::get_help", + ][::std::mem::offset_of!(cmdline_token_ops, get_help) - 24usize]; +}; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum cmdline_numtype { + UINT8 = 0, + UINT16 = 1, + UINT32 = 2, + UINT64 = 3, + INT8 = 4, + INT16 = 5, + INT32 = 6, + INT64 = 7, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct cmdline_token_num_data { + pub type_: cmdline_numtype, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of cmdline_token_num_data", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of cmdline_token_num_data", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: cmdline_token_num_data::type_", + ][::std::mem::offset_of!(cmdline_token_num_data, type_) - 0usize]; +}; +impl Default for cmdline_token_num_data { + 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 cmdline_token_num { + pub hdr: cmdline_token_hdr, + pub num_data: cmdline_token_num_data, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cmdline_token_num"][::std::mem::size_of::() - 24usize]; + [ + "Alignment of cmdline_token_num", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: cmdline_token_num::hdr", + ][::std::mem::offset_of!(cmdline_token_num, hdr) - 0usize]; + [ + "Offset of field: cmdline_token_num::num_data", + ][::std::mem::offset_of!(cmdline_token_num, num_data) - 16usize]; +}; +impl Default for cmdline_token_num { + 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 type cmdline_parse_token_num_t = cmdline_token_num; diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs new file mode 100644 index 0000000000..7d975cd979 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs @@ -0,0 +1,1723 @@ +#![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) }; + } + } +} +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, Clone, 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_1: __BindgenBitfieldUnit<[u8; 2usize]>, +} +#[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", + ][::std::mem::offset_of!(rte_eth_rxmode, mq_mode) - 0usize]; + [ + "Offset of field: rte_eth_rxmode::max_rx_pkt_len", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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, + 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, Clone, 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_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: u8, +} +#[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", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +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 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) } + } + #[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 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) } + } + #[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 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, + 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, Clone, 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, +} +#[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", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_rss_conf::rss_key", + ][::std::mem::offset_of!(rte_eth_rss_conf, rss_key) - 0usize]; + [ + "Offset of field: rte_eth_rss_conf::rss_key_len", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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(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, + ///< 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, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_vmdq_dcb_conf__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of rte_eth_vmdq_dcb_conf__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf__bindgen_ty_1::vlan_id", + ][::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", + ][::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", + ][::std::mem::size_of::() - 1040usize]; + [ + "Alignment of rte_eth_vmdq_dcb_conf", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf::nb_queue_pools", + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, nb_queue_pools) - 0usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf::enable_default_pool", + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, enable_default_pool) - 4usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf::default_pool", + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, default_pool) - 5usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf::nb_pool_maps", + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, nb_pool_maps) - 6usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_conf::pool_map", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, 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], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_dcb_rx_conf", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of rte_eth_dcb_rx_conf", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_dcb_rx_conf::nb_tcs", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, 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], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_vmdq_dcb_tx_conf", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of rte_eth_vmdq_dcb_tx_conf", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_vmdq_dcb_tx_conf::nb_queue_pools", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, 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], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_dcb_tx_conf", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of rte_eth_dcb_tx_conf", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_dcb_tx_conf::nb_tcs", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_eth_vmdq_tx_conf { + ///< VMDq mode, 64 pools. + pub nb_queue_pools: rte_eth_nb_pools, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_vmdq_tx_conf", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_eth_vmdq_tx_conf", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[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, + ///< 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, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_vmdq_rx_conf__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of rte_eth_vmdq_rx_conf__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf__bindgen_ty_1::vlan_id", + ][::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", + ][::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", + ][::std::mem::size_of::() - 1040usize]; + [ + "Alignment of rte_eth_vmdq_rx_conf", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::nb_queue_pools", + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, nb_queue_pools) - 0usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::enable_default_pool", + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, enable_default_pool) - 4usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::default_pool", + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, default_pool) - 5usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::enable_loop_back", + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, enable_loop_back) - 6usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::nb_pool_maps", + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, nb_pool_maps) - 7usize]; + [ + "Offset of field: rte_eth_vmdq_rx_conf::rx_mode", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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, Clone, 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, +} +#[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", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_ipv4_flow::src_ip", + ][::std::mem::offset_of!(rte_eth_ipv4_flow, src_ip) - 0usize]; + [ + "Offset of field: rte_eth_ipv4_flow::dst_ip", + ][::std::mem::offset_of!(rte_eth_ipv4_flow, dst_ip) - 4usize]; + [ + "Offset of field: rte_eth_ipv4_flow::tos", + ][::std::mem::offset_of!(rte_eth_ipv4_flow, tos) - 8usize]; + [ + "Offset of field: rte_eth_ipv4_flow::ttl", + ][::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)] +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, +} +#[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", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_ipv6_flow::src_ip", + ][::std::mem::offset_of!(rte_eth_ipv6_flow, src_ip) - 0usize]; + [ + "Offset of field: rte_eth_ipv6_flow::dst_ip", + ][::std::mem::offset_of!(rte_eth_ipv6_flow, dst_ip) - 16usize]; + [ + "Offset of field: rte_eth_ipv6_flow::tc", + ][::std::mem::offset_of!(rte_eth_ipv6_flow, tc) - 32usize]; + [ + "Offset of field: rte_eth_ipv6_flow::proto", + ][::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)] +#[derive(Debug, Default, Copy, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_fdir_masks", + ][::std::mem::size_of::() - 68usize]; + [ + "Alignment of rte_eth_fdir_masks", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_fdir_masks::vlan_tci_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, vlan_tci_mask) - 0usize]; + [ + "Offset of field: rte_eth_fdir_masks::ipv4_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, ipv4_mask) - 4usize]; + [ + "Offset of field: rte_eth_fdir_masks::ipv6_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, ipv6_mask) - 16usize]; + [ + "Offset of field: rte_eth_fdir_masks::src_port_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, src_port_mask) - 52usize]; + [ + "Offset of field: rte_eth_fdir_masks::dst_port_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, dst_port_mask) - 54usize]; + [ + "Offset of field: rte_eth_fdir_masks::mac_addr_byte_mask", + ][::std::mem::offset_of!(rte_eth_fdir_masks, mac_addr_byte_mask) - 56usize]; + [ + "Offset of field: rte_eth_fdir_masks::tunnel_id_mask", + ][::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)] +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, Clone, Hash, PartialEq, Eq)] +pub struct rte_eth_flex_payload_cfg { + ///< Payload type + pub type_: rte_eth_payload_type, + pub src_offset: [u16; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_flex_payload_cfg", + ][::std::mem::size_of::() - 36usize]; + [ + "Alignment of rte_eth_flex_payload_cfg", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_flex_payload_cfg::type_", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/** A structure used to define FDIR masks for flexible payload + for each flow type*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_eth_fdir_flex_mask { + pub flow_type: u16, + pub mask: [u8; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_fdir_flex_mask", + ][::std::mem::size_of::() - 18usize]; + [ + "Alignment of rte_eth_fdir_flex_mask", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: rte_eth_fdir_flex_mask::flow_type", + ][::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)] +#[derive(Debug, Copy, Clone, 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], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_fdir_flex_conf", + ][::std::mem::size_of::() - 688usize]; + [ + "Alignment of rte_eth_fdir_flex_conf", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_fdir_flex_conf::nb_payloads", + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, nb_payloads) - 0usize]; + [ + "Offset of field: rte_eth_fdir_flex_conf::nb_flexmasks", + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, nb_flexmasks) - 2usize]; + [ + "Offset of field: rte_eth_fdir_flex_conf::flex_set", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/** 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, Clone, 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, +} +#[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", + ][::std::mem::offset_of!(rte_fdir_conf, mode) - 0usize]; + [ + "Offset of field: rte_fdir_conf::pballoc", + ][::std::mem::offset_of!(rte_fdir_conf, pballoc) - 4usize]; + [ + "Offset of field: rte_fdir_conf::status", + ][::std::mem::offset_of!(rte_fdir_conf, status) - 8usize]; + [ + "Offset of field: rte_fdir_conf::drop_queue", + ][::std::mem::offset_of!(rte_fdir_conf, drop_queue) - 12usize]; + [ + "Offset of field: rte_fdir_conf::mask", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// A structure used to enable/disable specific device interrupts. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, 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, +} +#[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", + ][::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.*/ +#[repr(C)] +#[derive(Copy, Clone)] +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(Debug, Copy, Clone, Hash, PartialEq, Eq)] +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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_conf__bindgen_ty_1", + ][::std::mem::size_of::() - 2120usize]; + [ + "Alignment of rte_eth_conf__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_eth_conf__bindgen_ty_1::rss_conf", + ][::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", + ][::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", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rte_eth_conf__bindgen_ty_2 { + pub vmdq_dcb_tx_conf: rte_eth_vmdq_dcb_tx_conf, + pub dcb_tx_conf: rte_eth_dcb_tx_conf, + pub vmdq_tx_conf: rte_eth_vmdq_tx_conf, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_eth_conf__bindgen_ty_2", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of rte_eth_conf__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_eth_conf__bindgen_ty_2::vmdq_dcb_tx_conf", + ][::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", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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", + ][::std::mem::offset_of!(rte_eth_conf, link_speeds) - 0usize]; + [ + "Offset of field: rte_eth_conf::rxmode", + ][::std::mem::offset_of!(rte_eth_conf, rxmode) - 4usize]; + [ + "Offset of field: rte_eth_conf::txmode", + ][::std::mem::offset_of!(rte_eth_conf, txmode) - 16usize]; + [ + "Offset of field: rte_eth_conf::lpbk_mode", + ][::std::mem::offset_of!(rte_eth_conf, lpbk_mode) - 24usize]; + [ + "Offset of field: rte_eth_conf::rx_adv_conf", + ][::std::mem::offset_of!(rte_eth_conf, rx_adv_conf) - 32usize]; + [ + "Offset of field: rte_eth_conf::tx_adv_conf", + ][::std::mem::offset_of!(rte_eth_conf, tx_adv_conf) - 2152usize]; + [ + "Offset of field: rte_eth_conf::dcb_capability_en", + ][::std::mem::offset_of!(rte_eth_conf, dcb_capability_en) - 2164usize]; + [ + "Offset of field: rte_eth_conf::fdir_conf", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs new file mode 100644 index 0000000000..38f49fb4f0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs @@ -0,0 +1,84 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const RTE_CACHE_LINE_MIN_SIZE: u32 = 64; +pub const RTE_CACHE_LINE_SIZE: u32 = 64; +#[repr(C)] +#[repr(align(64))] +#[derive(Debug, Copy, Clone)] +pub struct rte_kni_mbuf { + pub buf_addr: *mut ::std::os::raw::c_void, + pub buf_physaddr: u64, + pub pad0: [::std::os::raw::c_char; 2usize], + ///< Start address of data in segment buffer. + pub data_off: u16, + pub pad1: [::std::os::raw::c_char; 2usize], + ///< Number of segments. + pub nb_segs: u8, + pub pad4: [::std::os::raw::c_char; 1usize], + ///< Offload features. + pub ol_flags: u64, + pub pad2: [::std::os::raw::c_char; 4usize], + ///< Total pkt len: sum of all segment data_len. + pub pkt_len: u32, + ///< Amount of data in segment buffer. + pub data_len: u16, + pub __bindgen_padding_0: [u8; 22usize], + pub pad3: [::std::os::raw::c_char; 8usize], + pub pool: *mut ::std::os::raw::c_void, + pub next: *mut ::std::os::raw::c_void, +} +#[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", + ][::std::mem::offset_of!(rte_kni_mbuf, buf_addr) - 0usize]; + [ + "Offset of field: rte_kni_mbuf::buf_physaddr", + ][::std::mem::offset_of!(rte_kni_mbuf, buf_physaddr) - 8usize]; + [ + "Offset of field: rte_kni_mbuf::pad0", + ][::std::mem::offset_of!(rte_kni_mbuf, pad0) - 16usize]; + [ + "Offset of field: rte_kni_mbuf::data_off", + ][::std::mem::offset_of!(rte_kni_mbuf, data_off) - 18usize]; + [ + "Offset of field: rte_kni_mbuf::pad1", + ][::std::mem::offset_of!(rte_kni_mbuf, pad1) - 20usize]; + [ + "Offset of field: rte_kni_mbuf::nb_segs", + ][::std::mem::offset_of!(rte_kni_mbuf, nb_segs) - 22usize]; + [ + "Offset of field: rte_kni_mbuf::pad4", + ][::std::mem::offset_of!(rte_kni_mbuf, pad4) - 23usize]; + [ + "Offset of field: rte_kni_mbuf::ol_flags", + ][::std::mem::offset_of!(rte_kni_mbuf, ol_flags) - 24usize]; + [ + "Offset of field: rte_kni_mbuf::pad2", + ][::std::mem::offset_of!(rte_kni_mbuf, pad2) - 32usize]; + [ + "Offset of field: rte_kni_mbuf::pkt_len", + ][::std::mem::offset_of!(rte_kni_mbuf, pkt_len) - 36usize]; + [ + "Offset of field: rte_kni_mbuf::data_len", + ][::std::mem::offset_of!(rte_kni_mbuf, data_len) - 40usize]; + [ + "Offset of field: rte_kni_mbuf::pad3", + ][::std::mem::offset_of!(rte_kni_mbuf, pad3) - 64usize]; + [ + "Offset of field: rte_kni_mbuf::pool", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs b/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs new file mode 100644 index 0000000000..0ccd40a5f8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs @@ -0,0 +1,357 @@ +#![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]); +impl __IncompleteArrayField { + #[inline] + pub const 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") + } +} +pub const RTE_CACHE_LINE_SIZE: u32 = 64; +pub const RTE_LIBRTE_IP_FRAG_MAX_FRAG: u32 = 4; +pub const IP_LAST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_LAST_FRAG_IDX; +pub const IP_FIRST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_FIRST_FRAG_IDX; +pub const IP_MIN_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MIN_FRAG_NUM; +pub const IP_MAX_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MAX_FRAG_NUM; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_1 { + ///< index of last fragment + IP_LAST_FRAG_IDX = 0, + ///< index of first fragment + IP_FIRST_FRAG_IDX = 1, + ///< minimum number of fragments + IP_MIN_FRAG_NUM = 2, + IP_MAX_FRAG_NUM = 4, +} +/// @internal fragmented mbuf +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_frag { + ///< offset into the packet + pub ofs: u16, + ///< length of fragment + pub len: u16, + ///< fragment mbuf + pub mb: *mut rte_mbuf, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// @internal to uniquely indetify fragmented datagram. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ip_frag_key { + ///< src address, first 8 bytes used for IPv4 + pub src_dst: [u64; 4usize], + ///< dst address + pub id: u32, + ///< src/dst key length + pub key_len: u32, +} +#[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", + ][::std::mem::offset_of!(ip_frag_key, src_dst) - 0usize]; + [ + "Offset of field: ip_frag_key::id", + ][::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(Debug, Copy, Clone)] +pub struct ip_frag_pkt { + ///< LRU list + pub lru: ip_frag_pkt__bindgen_ty_1, + ///< fragmentation key + pub key: ip_frag_key, + ///< creation timestamp + pub start: u64, + ///< expected reassembled size + pub total_size: u32, + ///< size of fragments received + pub frag_size: u32, + ///< index of next entry to fill + pub last_idx: u32, + ///< fragments + pub frags: [ip_frag; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_frag_pkt__bindgen_ty_1 { + pub tqe_next: *mut ip_frag_pkt, + pub tqe_prev: *mut *mut ip_frag_pkt, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ip_frag_pkt__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of ip_frag_pkt__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_next", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[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", + ][::std::mem::offset_of!(ip_frag_pkt, lru) - 0usize]; + [ + "Offset of field: ip_frag_pkt::key", + ][::std::mem::offset_of!(ip_frag_pkt, key) - 16usize]; + [ + "Offset of field: ip_frag_pkt::start", + ][::std::mem::offset_of!(ip_frag_pkt, start) - 56usize]; + [ + "Offset of field: ip_frag_pkt::total_size", + ][::std::mem::offset_of!(ip_frag_pkt, total_size) - 64usize]; + [ + "Offset of field: ip_frag_pkt::frag_size", + ][::std::mem::offset_of!(ip_frag_pkt, frag_size) - 68usize]; + [ + "Offset of field: ip_frag_pkt::last_idx", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_pkt_list { + pub tqh_first: *mut ip_frag_pkt, + pub tqh_last: *mut *mut ip_frag_pkt, +} +#[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", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// fragmentation table statistics +#[repr(C)] +#[repr(align(64))] +#[derive(Debug, Copy, Clone)] +pub struct ip_frag_tbl_stat { + ///< total # of find/insert attempts. + pub find_num: u64, + ///< # of add ops. + pub add_num: u64, + ///< # of del ops. + pub del_num: u64, + ///< # of reuse (del/add) ops. + pub reuse_num: u64, + ///< total # of add failures. + pub fail_total: u64, + ///< # of 'no space' add failures. + pub fail_nospace: u64, +} +#[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", + ][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: ip_frag_tbl_stat::find_num", + ][::std::mem::offset_of!(ip_frag_tbl_stat, find_num) - 0usize]; + [ + "Offset of field: ip_frag_tbl_stat::add_num", + ][::std::mem::offset_of!(ip_frag_tbl_stat, add_num) - 8usize]; + [ + "Offset of field: ip_frag_tbl_stat::del_num", + ][::std::mem::offset_of!(ip_frag_tbl_stat, del_num) - 16usize]; + [ + "Offset of field: ip_frag_tbl_stat::reuse_num", + ][::std::mem::offset_of!(ip_frag_tbl_stat, reuse_num) - 24usize]; + [ + "Offset of field: ip_frag_tbl_stat::fail_total", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/// fragmentation table +#[repr(C)] +#[repr(align(64))] +#[derive(Debug)] +pub struct rte_ip_frag_tbl { + ///< ttl for table entries. + pub max_cycles: u64, + ///< hash value mask. + pub entry_mask: u32, + ///< max entries allowed. + pub max_entries: u32, + ///< entries in use. + pub use_entries: u32, + ///< hash assocaitivity. + pub bucket_entries: u32, + ///< total size of the table. + pub nb_entries: u32, + ///< num of associativity lines. + pub nb_buckets: u32, + ///< last used entry. + pub last: *mut ip_frag_pkt, + ///< LRU list for table entries. + pub lru: ip_pkt_list, + pub __bindgen_padding_0: __BindgenOpaqueArray8<[u8; 8usize]>, + ///< statistics counters. + pub stat: ip_frag_tbl_stat, + ///< hash table. + pub pkt: __IncompleteArrayField, +} +#[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", + ][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: rte_ip_frag_tbl::max_cycles", + ][::std::mem::offset_of!(rte_ip_frag_tbl, max_cycles) - 0usize]; + [ + "Offset of field: rte_ip_frag_tbl::entry_mask", + ][::std::mem::offset_of!(rte_ip_frag_tbl, entry_mask) - 8usize]; + [ + "Offset of field: rte_ip_frag_tbl::max_entries", + ][::std::mem::offset_of!(rte_ip_frag_tbl, max_entries) - 12usize]; + [ + "Offset of field: rte_ip_frag_tbl::use_entries", + ][::std::mem::offset_of!(rte_ip_frag_tbl, use_entries) - 16usize]; + [ + "Offset of field: rte_ip_frag_tbl::bucket_entries", + ][::std::mem::offset_of!(rte_ip_frag_tbl, bucket_entries) - 20usize]; + [ + "Offset of field: rte_ip_frag_tbl::nb_entries", + ][::std::mem::offset_of!(rte_ip_frag_tbl, nb_entries) - 24usize]; + [ + "Offset of field: rte_ip_frag_tbl::nb_buckets", + ][::std::mem::offset_of!(rte_ip_frag_tbl, nb_buckets) - 28usize]; + [ + "Offset of field: rte_ip_frag_tbl::last", + ][::std::mem::offset_of!(rte_ip_frag_tbl, last) - 32usize]; + [ + "Offset of field: rte_ip_frag_tbl::lru", + ][::std::mem::offset_of!(rte_ip_frag_tbl, lru) - 40usize]; + [ + "Offset of field: rte_ip_frag_tbl::stat", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +///< fragment mbuf +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct rte_mbuf { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs new file mode 100644 index 0000000000..ce6c58e39e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs @@ -0,0 +1,1228 @@ +#![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) }; + } + } +} +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, Clone, Hash, PartialEq, Eq)] +pub struct rte_atomic16_t { + ///< An internal counter value. + pub cnt: i16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_atomic16_t"][::std::mem::size_of::() - 2usize]; + ["Alignment of rte_atomic16_t"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: rte_atomic16_t::cnt", + ][::std::mem::offset_of!(rte_atomic16_t, cnt) - 0usize]; +}; +/// The generic rte_mbuf, containing a packet mbuf. +#[repr(C)] +#[repr(align(64))] +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, +} +/** 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(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_1 { + ///< Atomically accessed refcnt + pub refcnt_atomic: rte_atomic16_t, + ///< Non-atomically accessed refcnt + pub refcnt: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_1", + ][::std::mem::size_of::() - 2usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_1::refcnt_atomic", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_1, refcnt_atomic) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_1::refcnt", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_1, refcnt) - 0usize]; +}; +impl Default for rte_mbuf__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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_2 { + ///< L2/L3/L4 and tunnel information. + pub packet_type: u32, + pub __bindgen_anon_1: rte_mbuf__bindgen_ty_2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_mbuf__bindgen_ty_2__bindgen_ty_1 { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_2__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_2__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; +}; +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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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, + 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 + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_2::packet_type", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_2, packet_type) - 0usize]; +}; +impl Default for rte_mbuf__bindgen_ty_2 { + 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(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_3 { + ///< RSS hash result if RSS enabled + pub rss: u32, + ///< Filter identifier if FDIR enabled + pub fdir: rte_mbuf__bindgen_ty_3__bindgen_ty_1, + ///< Hierarchical scheduler + pub sched: rte_mbuf__bindgen_ty_3__bindgen_ty_2, + ///< User defined tags. See rte_distributor_process() + pub usr: u32, +} +#[repr(C)] +#[derive(Copy, Clone)] +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(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1 { + pub __bindgen_anon_1: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + pub lo: u32, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::< + rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + >() - 4usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::< + rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + >() - 2usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1::hash", + ][::std::mem::offset_of!( + rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, hash + ) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1::id", + ][::std::mem::offset_of!( + rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, id + ) - 2usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() + - 4usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() + - 4usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1::lo", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, lo) + - 0usize]; +}; +impl Default for rte_mbuf__bindgen_ty_3__bindgen_ty_1__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1::hi", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3__bindgen_ty_1, hi) - 4usize]; +}; +impl Default for rte_mbuf__bindgen_ty_3__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() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_2 { + pub lo: u32, + pub hi: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_2", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_2::lo", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3__bindgen_ty_2, lo) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_2::hi", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3__bindgen_ty_2, hi) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_3", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_3", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3::rss", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3, rss) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3::fdir", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3, fdir) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3::sched", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3, sched) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_3::usr", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_3, usr) - 0usize]; +}; +impl Default for rte_mbuf__bindgen_ty_3 { + 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(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_4 { + ///< Can be used for external metadata + pub userdata: *mut ::std::os::raw::c_void, + ///< Allow 8-byte userdata on 32-bit + pub udata64: u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_4", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_4", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_4::userdata", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_4, userdata) - 0usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_4::udata64", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_4, udata64) - 0usize]; +}; +impl Default for rte_mbuf__bindgen_ty_4 { + 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(Copy, Clone)] +pub union rte_mbuf__bindgen_ty_5 { + ///< combined for easy fetch + pub tx_offload: u64, + pub __bindgen_anon_1: rte_mbuf__bindgen_ty_5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { + pub _bindgen_align: [u64; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, + pub __bindgen_padding_0: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_5__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_5__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; +}; +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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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) } + } + #[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 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, + 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 + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of rte_mbuf__bindgen_ty_5", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of rte_mbuf__bindgen_ty_5", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: rte_mbuf__bindgen_ty_5::tx_offload", + ][::std::mem::offset_of!(rte_mbuf__bindgen_ty_5, tx_offload) - 0usize]; +}; +impl Default for rte_mbuf__bindgen_ty_5 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_mbuf"][::std::mem::size_of::() - 128usize]; + ["Alignment of rte_mbuf"][::std::mem::align_of::() - 64usize]; + [ + "Offset of field: rte_mbuf::cacheline0", + ][::std::mem::offset_of!(rte_mbuf, cacheline0) - 0usize]; + [ + "Offset of field: rte_mbuf::buf_addr", + ][::std::mem::offset_of!(rte_mbuf, buf_addr) - 0usize]; + [ + "Offset of field: rte_mbuf::buf_physaddr", + ][::std::mem::offset_of!(rte_mbuf, buf_physaddr) - 8usize]; + [ + "Offset of field: rte_mbuf::buf_len", + ][::std::mem::offset_of!(rte_mbuf, buf_len) - 16usize]; + [ + "Offset of field: rte_mbuf::rearm_data", + ][::std::mem::offset_of!(rte_mbuf, rearm_data) - 18usize]; + [ + "Offset of field: rte_mbuf::data_off", + ][::std::mem::offset_of!(rte_mbuf, data_off) - 18usize]; + [ + "Offset of field: rte_mbuf::nb_segs", + ][::std::mem::offset_of!(rte_mbuf, nb_segs) - 22usize]; + [ + "Offset of field: rte_mbuf::port", + ][::std::mem::offset_of!(rte_mbuf, port) - 23usize]; + [ + "Offset of field: rte_mbuf::ol_flags", + ][::std::mem::offset_of!(rte_mbuf, ol_flags) - 24usize]; + [ + "Offset of field: rte_mbuf::rx_descriptor_fields1", + ][::std::mem::offset_of!(rte_mbuf, rx_descriptor_fields1) - 32usize]; + [ + "Offset of field: rte_mbuf::pkt_len", + ][::std::mem::offset_of!(rte_mbuf, pkt_len) - 36usize]; + [ + "Offset of field: rte_mbuf::data_len", + ][::std::mem::offset_of!(rte_mbuf, data_len) - 40usize]; + [ + "Offset of field: rte_mbuf::vlan_tci", + ][::std::mem::offset_of!(rte_mbuf, vlan_tci) - 42usize]; + [ + "Offset of field: rte_mbuf::hash", + ][::std::mem::offset_of!(rte_mbuf, hash) - 44usize]; + [ + "Offset of field: rte_mbuf::seqn", + ][::std::mem::offset_of!(rte_mbuf, seqn) - 52usize]; + [ + "Offset of field: rte_mbuf::vlan_tci_outer", + ][::std::mem::offset_of!(rte_mbuf, vlan_tci_outer) - 56usize]; + [ + "Offset of field: rte_mbuf::cacheline1", + ][::std::mem::offset_of!(rte_mbuf, cacheline1) - 64usize]; + [ + "Offset of field: rte_mbuf::pool", + ][::std::mem::offset_of!(rte_mbuf, pool) - 72usize]; + [ + "Offset of field: rte_mbuf::next", + ][::std::mem::offset_of!(rte_mbuf, next) - 80usize]; + [ + "Offset of field: rte_mbuf::priv_size", + ][::std::mem::offset_of!(rte_mbuf, priv_size) - 96usize]; + [ + "Offset of field: rte_mbuf::timesync", + ][::std::mem::offset_of!(rte_mbuf, timesync) - 98usize]; +}; +impl Default for rte_mbuf { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +///< Pool from which mbuf was allocated. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct rte_mempool { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs b/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs new file mode 100644 index 0000000000..098beb43de --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub static mut b: ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/constified-enum-module-overflow.rs b/bindgen-tests/tests/expectations/tests/libclang-9/constified-enum-module-overflow.rs new file mode 100644 index 0000000000..4f8296c65c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/constified-enum-module-overflow.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct B { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct C { + pub _address: u8, +} +pub type C_U = B; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub u: 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]; + ["Offset of field: A::u"][::std::mem::offset_of!(A, u) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: C_open0_A_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: C_open0_A_close0", + ][::std::mem::align_of::() - 1usize]; +}; 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 new file mode 100644 index 0000000000..d64a8948ee --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/issue-544-stylo-creduce-2.rs @@ -0,0 +1,25 @@ +#![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 __BindgenOpaqueArray<[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/issue-753.rs b/bindgen-tests/tests/expectations/tests/libclang-9/issue-753.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/issue-753.rs @@ -0,0 +1 @@ +#![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/libclang-9/macro_fallback_non_system_dir.rs b/bindgen-tests/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs new file mode 100644 index 0000000000..8f5c4ba2da --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs @@ -0,0 +1 @@ +pub const NEGATIVE: i32 = -1; diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/ptr32-has-different-size.rs b/bindgen-tests/tests/expectations/tests/libclang-9/ptr32-has-different-size.rs new file mode 100644 index 0000000000..f55f88f496 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/ptr32-has-different-size.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TEST_STRUCT { + pub ptr_32bit: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TEST_STRUCT"][::std::mem::size_of::() - 8usize]; + ["Alignment of TEST_STRUCT"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: TEST_STRUCT::ptr_32bit", + ][::std::mem::offset_of!(TEST_STRUCT, ptr_32bit) - 0usize]; +}; +impl Default for TEST_STRUCT { + 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 type TEST = TEST_STRUCT; diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/struct_typedef_ns.rs b/bindgen-tests/tests/expectations/tests/libclang-9/struct_typedef_ns.rs new file mode 100644 index 0000000000..d93a62e746 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/libclang-9/struct_typedef_ns.rs @@ -0,0 +1,57 @@ +#![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 whatever { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct typedef_struct { + pub foo: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of typedef_struct"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of typedef_struct", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: typedef_struct::foo", + ][::std::mem::offset_of!(typedef_struct, foo) - 0usize]; + }; + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum typedef_enum { + BAR = 1, + } + } + pub mod _bindgen_mod_id_12 { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct _bindgen_ty_1 { + pub foo: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 4usize]; + [ + "Alignment of _bindgen_ty_1", + ][::std::mem::align_of::<_bindgen_ty_1>() - 4usize]; + [ + "Offset of field: _bindgen_ty_1::foo", + ][::std::mem::offset_of!(_bindgen_ty_1, foo) - 0usize]; + }; + pub type typedef_struct = root::_bindgen_mod_id_12::_bindgen_ty_1; + pub const _bindgen_mod_id_12_BAR: root::_bindgen_mod_id_12::_bindgen_ty_2 = _bindgen_ty_2::BAR; + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum _bindgen_ty_2 { + BAR = 1, + } + pub use self::super::super::root::_bindgen_mod_id_12::_bindgen_ty_2 as typedef_enum; + } +} diff --git a/tests/expectations/tests/libclang_version_specific_generated_tests.rs b/bindgen-tests/tests/expectations/tests/libclang_version_specific_generated_tests.rs similarity index 100% rename from tests/expectations/tests/libclang_version_specific_generated_tests.rs rename to bindgen-tests/tests/expectations/tests/libclang_version_specific_generated_tests.rs diff --git a/bindgen-tests/tests/expectations/tests/long_double.rs b/bindgen-tests/tests/expectations/tests/long_double.rs new file mode 100644 index 0000000000..4a8b13e9b0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/long_double.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct foo { + pub bar: u128, +} +#[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-basic.rs b/bindgen-tests/tests/expectations/tests/macro-expr-basic.rs new file mode 100644 index 0000000000..21c81b317c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/macro-expr-basic.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO: u32 = 1; +pub const BAR: u32 = 4; +pub const BAZ: u32 = 5; +pub const MIN: i64 = -9223372036854775808; +pub const BARR: u32 = 1; +pub const BAZZ: u32 = 7; +pub const I_RAN_OUT_OF_DUMB_NAMES: u32 = 7; +pub const HAZ_A_COMMENT: u32 = 1; +pub const HAZ_A_COMMENT_INSIDE: u32 = 2; diff --git a/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs b/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs new file mode 100644 index 0000000000..785ef4bb9f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const MODBUS_WOOT: u32 = 3; +unsafe extern "C" { + pub fn foo(); +} diff --git a/bindgen-tests/tests/expectations/tests/macro-redef.rs b/bindgen-tests/tests/expectations/tests/macro-redef.rs new file mode 100644 index 0000000000..12e3d3d587 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/macro-redef.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO: u32 = 4; +pub const BAR: u32 = 5; +pub const BAZ: u32 = 6; diff --git a/bindgen-tests/tests/expectations/tests/macro_const.rs b/bindgen-tests/tests/expectations/tests/macro_const.rs new file mode 100644 index 0000000000..e4e27dea52 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/macro_const.rs @@ -0,0 +1,8 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const foo: &[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: &[u8; 5] = b"\xF0(\x8C(\0"; diff --git a/bindgen-tests/tests/expectations/tests/maddness-is-avoidable.rs b/bindgen-tests/tests/expectations/tests/maddness-is-avoidable.rs new file mode 100644 index 0000000000..0876aeb904 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/maddness-is-avoidable.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct RefPtr { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct RefPtr_Proxy { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/mangling-ios.rs b/bindgen-tests/tests/expectations/tests/mangling-ios.rs new file mode 100644 index 0000000000..736d379f01 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-ios.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..b6ed9146da --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-linux32.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo4sBarE"] + pub static mut Foo_sBar: bool; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/mangling-linux64.rs b/bindgen-tests/tests/expectations/tests/mangling-linux64.rs new file mode 100644 index 0000000000..b6ed9146da --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-linux64.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo4sBarE"] + pub static mut Foo_sBar: bool; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/mangling-macos.rs b/bindgen-tests/tests/expectations/tests/mangling-macos.rs new file mode 100644 index 0000000000..237859e23b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-macos.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}__ZN3Foo4sBarE"] + pub static mut Foo_sBar: bool; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/mangling-win32.rs b/bindgen-tests/tests/expectations/tests/mangling-win32.rs new file mode 100644 index 0000000000..263f619374 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-win32.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target = "i686-pc-windows-msvc")] +unsafe extern "C" { + pub fn foo(); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}?sBar@Foo@@2_NA"] + pub static mut Foo_sBar: bool; +} +#[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 "fastcall" { + pub fn fast_call_func_no_args() -> ::std::os::raw::c_int; +} +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; +} +unsafe extern "stdcall" { + pub fn std_call_func_no_args() -> ::std::os::raw::c_int; +} +unsafe extern "stdcall" { + pub fn std_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; +} diff --git a/bindgen-tests/tests/expectations/tests/mangling-win64.rs b/bindgen-tests/tests/expectations/tests/mangling-win64.rs new file mode 100644 index 0000000000..2a782480ed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mangling-win64.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo(); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}?sBar@Foo@@2_NA"] + pub static mut Foo_sBar: bool; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; 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_pre_1_82.rs b/bindgen-tests/tests/expectations/tests/merge_extern_blocks_pre_1_82.rs new file mode 100644 index 0000000000..595d865af1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/merge_extern_blocks_pre_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]; + }; + 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; + } + } + 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/method-mangling.rs b/bindgen-tests/tests/expectations/tests/method-mangling.rs new file mode 100644 index 0000000000..4c86825cce --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/method-mangling.rs @@ -0,0 +1,21 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Foo4typeEv"] + pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_int; +} +impl Foo { + #[inline] + pub unsafe fn type_(&mut self) -> ::std::os::raw::c_int { + Foo_type(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/module-allowlisted.rs b/bindgen-tests/tests/expectations/tests/module-allowlisted.rs new file mode 100644 index 0000000000..9ac408dc8f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/module-allowlisted.rs @@ -0,0 +1,16 @@ +#![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 Test { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Test"][::std::mem::size_of::() - 1usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/msvc-no-usr.rs b/bindgen-tests/tests/expectations/tests/msvc-no-usr.rs new file mode 100644 index 0000000000..adaa1a07b2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/msvc-no-usr.rs @@ -0,0 +1,12 @@ +#![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 foo: usize, +} +#[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::foo"][::std::mem::offset_of!(A, foo) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs b/bindgen-tests/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs new file mode 100644 index 0000000000..b0cf27451c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs @@ -0,0 +1,31 @@ +#![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]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 1usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/mutable.rs b/bindgen-tests/tests/expectations/tests/mutable.rs new file mode 100644 index 0000000000..ff98d31f24 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/mutable.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct C { + pub m_member: ::std::os::raw::c_int, + pub m_other: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 8usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::m_member"][::std::mem::offset_of!(C, m_member) - 0usize]; + ["Offset of field: C::m_other"][::std::mem::offset_of!(C, m_other) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct NonCopiable { + pub m_member: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NonCopiable"][::std::mem::size_of::() - 4usize]; + ["Alignment of NonCopiable"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: NonCopiable::m_member", + ][::std::mem::offset_of!(NonCopiable, m_member) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default)] +pub struct NonCopiableWithNonCopiableMutableMember { + pub m_member: NonCopiable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of NonCopiableWithNonCopiableMutableMember", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of NonCopiableWithNonCopiableMutableMember", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: NonCopiableWithNonCopiableMutableMember::m_member", + ][::std::mem::offset_of!(NonCopiableWithNonCopiableMutableMember, m_member) + - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/namespace.rs b/bindgen-tests/tests/expectations/tests/namespace.rs new file mode 100644 index 0000000000..4e58fa7ab1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/namespace.rs @@ -0,0 +1,101 @@ +#![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; + unsafe extern "C" { + #[link_name = "\u{1}_Z9top_levelv"] + pub fn top_level(); + } + pub mod whatever { + #[allow(unused_imports)] + use self::super::super::root; + pub type whatever_other_thing_t = whatever_int_t; + pub type whatever_int_t = ::std::os::raw::c_int; + unsafe extern "C" { + #[link_name = "\u{1}_ZN8whatever11in_whateverEv"] + pub fn in_whatever(); + } + } + pub mod _bindgen_mod_id_17 { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct A { + pub b: root::whatever::whatever_int_t, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of A"][::std::mem::size_of::() - 4usize]; + ["Alignment of A"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A::b"][::std::mem::offset_of!(A, b) - 0usize]; + }; + } + #[repr(C)] + #[derive(Debug)] + pub struct C { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _base: root::_bindgen_mod_id_17::A, + pub m_c: T, + pub m_c_ptr: *mut T, + pub m_c_arr: [T; 10usize], + } + 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() + } + } + } + pub mod w { + #[allow(unused_imports)] + use self::super::super::root; + pub type whatever_int_t = ::std::os::raw::c_uint; + #[repr(C)] + #[derive(Debug)] + pub struct D { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_c: root::C, + } + impl Default for D { + 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}_ZN1w3hehEv"] + pub fn heh() -> root::w::whatever_int_t; + } + unsafe extern "C" { + #[link_name = "\u{1}_ZN1w3fooEv"] + pub fn foo() -> root::C<::std::os::raw::c_int>; + } + unsafe extern "C" { + #[link_name = "\u{1}_ZN1w4barrEv"] + pub fn barr() -> root::C; + } + } + pub mod foobar { + #[allow(unused_imports)] + use self::super::super::root; + unsafe extern "C" { + #[link_name = "\u{1}_ZN6foobar3fooEv"] + pub fn foo(); + } + } + pub mod faraway { + #[allow(unused_imports)] + use self::super::super::root; + 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-template-typedef.rs b/bindgen-tests/tests/expectations/tests/nested-template-typedef.rs new file mode 100644 index 0000000000..4a4dd2ffe1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/nested-template-typedef.rs @@ -0,0 +1,11 @@ +#![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, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo_Bar { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/nested.rs b/bindgen-tests/tests/expectations/tests/nested.rs new file mode 100644 index 0000000000..5e0a8b07c8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/nested.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Calc { + pub w: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Calc"][::std::mem::size_of::() - 4usize]; + ["Alignment of Calc"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Calc::w"][::std::mem::offset_of!(Calc, w) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test_Size { + pub mWidth: Test_Size_Dimension, + pub mHeight: Test_Size_Dimension, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test_Size_Dimension { + pub _base: Calc, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of Test_Size_Dimension", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of Test_Size_Dimension", + ][::std::mem::align_of::() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test_Size"][::std::mem::size_of::() - 8usize]; + ["Alignment of Test_Size"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Test_Size::mWidth", + ][::std::mem::offset_of!(Test_Size, mWidth) - 0usize]; + [ + "Offset of field: Test_Size::mHeight", + ][::std::mem::offset_of!(Test_Size, mHeight) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 1usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/nested_vtable.rs b/bindgen-tests/tests/expectations/tests/nested_vtable.rs new file mode 100644 index 0000000000..12aa2ea441 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/nested_vtable.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct nsISupports__bindgen_vtable { + pub nsISupports_QueryInterface: unsafe extern "C" fn( + this: *mut nsISupports, + ) -> *mut nsISupports, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsISupports { + pub vtable_: *const nsISupports__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsISupports"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsISupports"][::std::mem::align_of::() - 8usize]; +}; +impl Default for nsISupports { + 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}_ZN11nsISupports14QueryInterfaceEv"] + pub fn nsISupports_QueryInterface( + this: *mut ::std::os::raw::c_void, + ) -> *mut nsISupports; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsIRunnable { + pub _base: nsISupports, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsIRunnable"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsIRunnable"][::std::mem::align_of::() - 8usize]; +}; +impl Default for nsIRunnable { + 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 Runnable { + pub _base: nsIRunnable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Runnable"][::std::mem::size_of::() - 8usize]; + ["Alignment of Runnable"][::std::mem::align_of::() - 8usize]; +}; +impl Default for Runnable { + 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/nested_within_namespace.rs b/bindgen-tests/tests/expectations/tests/nested_within_namespace.rs new file mode 100644 index 0000000000..f470571ddc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/nested_within_namespace.rs @@ -0,0 +1,45 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar { + pub foo: ::std::os::raw::c_int, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar_Baz { + pub foo: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Bar_Baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of Bar_Baz"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Bar_Baz::foo", + ][::std::mem::offset_of!(Bar_Baz, foo) - 0usize]; + }; + #[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]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Baz { + pub baz: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 4usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Baz::baz"][::std::mem::offset_of!(Baz, baz) - 0usize]; + }; + } +} 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 new file mode 100644 index 0000000000..0045c52a61 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/newtype-enum.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +impl Foo { + pub const Bar: Foo = Foo(2); + pub const Baz: Foo = Foo(4); + pub const Duplicated: Foo = Foo(4); + pub const Negative: Foo = Foo(-3); +} +#[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/newtype-global-enum.rs b/bindgen-tests/tests/expectations/tests/newtype-global-enum.rs new file mode 100644 index 0000000000..29b87bff06 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/newtype-global-enum.rs @@ -0,0 +1,8 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const Foo_Bar: Foo = Foo(2); +pub const Foo_Baz: Foo = Foo(4); +pub const Foo_Duplicated: Foo = Foo(4); +pub const Foo_Negative: Foo = Foo(-3); +#[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/no-comments.rs b/bindgen-tests/tests/expectations/tests/no-comments.rs new file mode 100644 index 0000000000..6a60973fb4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-comments.rs @@ -0,0 +1,12 @@ +#![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 s: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::s"][::std::mem::offset_of!(Foo, s) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-derive-debug.rs b/bindgen-tests/tests/expectations/tests/no-derive-debug.rs new file mode 100644 index 0000000000..5e525068fd --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-derive-debug.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct foo { + bar: ::std::os::raw::c_int, +} +/** bar should compile. It will normally derive debug, but our blocklist of foo + and replacement for another type that doesn't implement it would prevent it + from building if --no-derive-debug didn't work.*/ +#[repr(C)] +pub struct bar { + pub foo: foo, + pub baz: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: bar::foo"][::std::mem::offset_of!(bar, foo) - 0usize]; + ["Offset of field: bar::baz"][::std::mem::offset_of!(bar, baz) - 4usize]; +}; +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/no-derive-default.rs b/bindgen-tests/tests/expectations/tests/no-derive-default.rs new file mode 100644 index 0000000000..a1d86a6502 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-derive-default.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct foo { + bar: ::std::os::raw::c_int, +} +/** bar should compile. It will normally derive default, but our blocklist of foo + and replacement for another type that doesn't implement it would prevent it + from building if --no-derive-default didn't work.*/ +#[repr(C)] +pub struct bar { + pub foo: foo, + pub baz: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: bar::foo"][::std::mem::offset_of!(bar, foo) - 0usize]; + ["Offset of field: bar::baz"][::std::mem::offset_of!(bar, baz) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-hash-allowlisted.rs b/bindgen-tests/tests/expectations/tests/no-hash-allowlisted.rs new file mode 100644 index 0000000000..ff4dd1e38e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-hash-allowlisted.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct NoHash { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoHash"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoHash"][::std::mem::align_of::() - 4usize]; + ["Offset of field: NoHash::i"][::std::mem::offset_of!(NoHash, i) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-hash-opaque.rs b/bindgen-tests/tests/expectations/tests/no-hash-opaque.rs new file mode 100644 index 0000000000..9dc9e01989 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-hash-opaque.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone)] +pub struct NoHash { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoHash"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoHash"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-partialeq-allowlisted.rs b/bindgen-tests/tests/expectations/tests/no-partialeq-allowlisted.rs new file mode 100644 index 0000000000..68ae1a7449 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-partialeq-allowlisted.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct NoPartialEq { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoPartialEq"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoPartialEq"][::std::mem::align_of::() - 4usize]; + ["Offset of field: NoPartialEq::i"][::std::mem::offset_of!(NoPartialEq, i) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-partialeq-opaque.rs b/bindgen-tests/tests/expectations/tests/no-partialeq-opaque.rs new file mode 100644 index 0000000000..4b488df6a5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-partialeq-opaque.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone)] +pub struct NoPartialEq { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoPartialEq"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoPartialEq"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no-recursive-allowlisting.rs b/bindgen-tests/tests/expectations/tests/no-recursive-allowlisting.rs new file mode 100644 index 0000000000..dc1e4721ab --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-recursive-allowlisting.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub enum Bar {} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + pub baz: *mut Bar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Foo::baz"][::std::mem::offset_of!(Foo, baz) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/no-std.rs b/bindgen-tests/tests/expectations/tests/no-std.rs new file mode 100644 index 0000000000..0f03c222ef --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no-std.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![no_std] +mod libc { + pub type c_int = i32; + pub enum c_void {} +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub a: libc::c_int, + pub b: libc::c_int, + pub bar: *mut libc::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::core::mem::size_of::() - 16usize]; + ["Alignment of foo"][::core::mem::align_of::() - 8usize]; + ["Offset of field: foo::a"][::core::mem::offset_of!(foo, a) - 0usize]; + ["Offset of field: foo::b"][::core::mem::offset_of!(foo, b) - 4usize]; + ["Offset of field: foo::bar"][::core::mem::offset_of!(foo, bar) - 8usize]; +}; +impl Default for foo { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/no_copy.rs b/bindgen-tests/tests/expectations/tests/no_copy.rs new file mode 100644 index 0000000000..b92c542482 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_copy.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Debug, Default)] +pub struct CopiableButWait { + pub whatever: ::std::os::raw::c_int, +} diff --git a/bindgen-tests/tests/expectations/tests/no_copy_allowlisted.rs b/bindgen-tests/tests/expectations/tests/no_copy_allowlisted.rs new file mode 100644 index 0000000000..67be391799 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_copy_allowlisted.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct NoCopy { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoCopy"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoCopy"][::std::mem::align_of::() - 4usize]; + ["Offset of field: NoCopy::i"][::std::mem::offset_of!(NoCopy, i) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no_copy_opaque.rs b/bindgen-tests/tests/expectations/tests/no_copy_opaque.rs new file mode 100644 index 0000000000..dea6a0a6cf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_copy_opaque.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default)] +pub struct NoCopy { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoCopy"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoCopy"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no_debug.rs b/bindgen-tests/tests/expectations/tests/no_debug.rs new file mode 100644 index 0000000000..9a162c6f70 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_debug.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Default, Copy, Clone)] +pub struct DebugButWait { + pub whatever: ::std::os::raw::c_int, +} diff --git a/bindgen-tests/tests/expectations/tests/no_debug_allowlisted.rs b/bindgen-tests/tests/expectations/tests/no_debug_allowlisted.rs new file mode 100644 index 0000000000..1ddb20a747 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_debug_allowlisted.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Default, Copy, Clone)] +pub struct NoDebug { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoDebug"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoDebug"][::std::mem::align_of::() - 4usize]; + ["Offset of field: NoDebug::i"][::std::mem::offset_of!(NoDebug, i) - 0usize]; +}; 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 new file mode 100644 index 0000000000..ceec3823ae --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_debug_bypass_impl_debug.rs @@ -0,0 +1,30 @@ +#![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], +} +impl Default for Generic { + 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 NoDebug { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: [T; 40usize], +} +impl Default for NoDebug { + 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/no_debug_opaque.rs b/bindgen-tests/tests/expectations/tests/no_debug_opaque.rs new file mode 100644 index 0000000000..0bb37ec711 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_debug_opaque.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(4))] +#[derive(Default, Copy, Clone)] +pub struct NoDebug { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoDebug"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoDebug"][::std::mem::align_of::() - 4usize]; +}; diff --git a/tests/expectations/tests/no_default.rs b/bindgen-tests/tests/expectations/tests/no_default.rs similarity index 83% rename from tests/expectations/tests/no_default.rs rename to bindgen-tests/tests/expectations/tests/no_default.rs index 22fdbf36e4..fd3d86e277 100644 --- a/tests/expectations/tests/no_default.rs +++ b/bindgen-tests/tests/expectations/tests/no_default.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] ///
#[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/bindgen-tests/tests/expectations/tests/no_default_allowlisted.rs b/bindgen-tests/tests/expectations/tests/no_default_allowlisted.rs new file mode 100644 index 0000000000..593e644343 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_default_allowlisted.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NoDefault { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoDefault"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoDefault"][::std::mem::align_of::() - 4usize]; + ["Offset of field: NoDefault::i"][::std::mem::offset_of!(NoDefault, i) - 0usize]; +}; diff --git a/tests/expectations/tests/no_default_bypass_derive_default.rs b/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs similarity index 81% rename from tests/expectations/tests/no_default_bypass_derive_default.rs rename to bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs index 6c44a9dd28..3dfd34474a 100644 --- a/tests/expectations/tests/no_default_bypass_derive_default.rs +++ b/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs @@ -1,14 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] +#[derive(Debug)] pub struct Generic { - pub t: [T; 40usize], pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: [T; 40usize], } impl Default for Generic { fn default() -> Self { @@ -20,7 +15,8 @@ impl Default for Generic { } } #[repr(C)] +#[derive(Debug)] pub struct NoDefault { - pub t: [T; 40usize], pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: [T; 40usize], } diff --git a/bindgen-tests/tests/expectations/tests/no_default_opaque.rs b/bindgen-tests/tests/expectations/tests/no_default_opaque.rs new file mode 100644 index 0000000000..ba2f63f91c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_default_opaque.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Copy, Clone)] +pub struct NoDefault { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoDefault"][::std::mem::size_of::() - 4usize]; + ["Alignment of NoDefault"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/no_size_t_is_usize.rs b/bindgen-tests/tests/expectations/tests/no_size_t_is_usize.rs new file mode 100644 index 0000000000..94ce735b31 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/no_size_t_is_usize.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type size_t = ::std::os::raw::c_ulong; +pub type ssize_t = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + pub len: size_t, + pub offset: ssize_t, + pub next: *mut A, +} +#[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::len"][::std::mem::offset_of!(A, len) - 0usize]; + ["Offset of field: A::offset"][::std::mem::offset_of!(A, offset) - 8usize]; + ["Offset of field: A::next"][::std::mem::offset_of!(A, next) - 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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/non-type-params.rs b/bindgen-tests/tests/expectations/tests/non-type-params.rs new file mode 100644 index 0000000000..325620b9bb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/non-type-params.rs @@ -0,0 +1,32 @@ +#![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 = __BindgenOpaqueArray<[u32; 4usize]>; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct UsesArray { + 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)] +const _: () = { + ["Size of UsesArray"][::std::mem::size_of::() - 40usize]; + ["Alignment of UsesArray"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: UsesArray::array_char_16", + ][::std::mem::offset_of!(UsesArray, array_char_16) - 0usize]; + [ + "Offset of field: UsesArray::array_bool_8", + ][::std::mem::offset_of!(UsesArray, array_bool_8) - 16usize]; + [ + "Offset of field: UsesArray::array_int_4", + ][::std::mem::offset_of!(UsesArray, array_int_4) - 24usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/noreturn.rs b/bindgen-tests/tests/expectations/tests/noreturn.rs new file mode 100644 index 0000000000..0e601b5510 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/noreturn.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z1fv"] + pub fn f() -> !; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z1gv"] + pub fn g() -> !; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z1hv"] + pub fn h() -> !; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z1iPFvvE"] + pub fn i(arg: ::std::option::Option !>); +} +unsafe extern "C" { + #[link_name = "\u{1}_Z1jPFvvE"] + pub fn j(arg: ::std::option::Option !>) -> !; +} diff --git a/tests/expectations/tests/nsBaseHashtable.rs b/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs similarity index 77% rename from tests/expectations/tests/nsBaseHashtable.rs rename to bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs index d7607b91ab..81b9f000c6 100644 --- a/tests/expectations/tests/nsBaseHashtable.rs +++ b/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs @@ -1,11 +1,12 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type size_t = ::std::os::raw::c_ulonglong; +#![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 { @@ -21,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/tests/expectations/tests/nsStyleAutoArray.rs b/bindgen-tests/tests/expectations/tests/nsStyleAutoArray.rs similarity index 91% rename from tests/expectations/tests/nsStyleAutoArray.rs rename to bindgen-tests/tests/expectations/tests/nsStyleAutoArray.rs index fab18c1cab..3d8edcfdc1 100644 --- a/tests/expectations/tests/nsStyleAutoArray.rs +++ b/bindgen-tests/tests/expectations/tests/nsStyleAutoArray.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsTArray { - pub mBuff: *mut T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub mBuff: *mut T, } impl Default for nsTArray { fn default() -> Self { @@ -23,9 +17,9 @@ impl Default for nsTArray { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct nsStyleAutoArray { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub mFirstElement: T, pub mOtherElements: nsTArray, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } #[repr(i32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/bindgen-tests/tests/expectations/tests/objc_allowlist.rs b/bindgen-tests/tests/expectations/tests/objc_allowlist.rs new file mode 100644 index 0000000000..7ccd4e3c04 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_allowlist.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +pub trait PSomeProtocol: Sized + std::ops::Deref { + unsafe fn protocolMethod(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, protocolMethod) + } + unsafe fn protocolClassMethod() + where + ::Target: objc::Message + Sized, + { + msg_send!(class!(SomeProtocol), protocolClassMethod) + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct AllowlistMe(pub id); +impl std::ops::Deref for AllowlistMe { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for AllowlistMe {} +impl AllowlistMe { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(AllowlistMe), alloc) }) + } +} +impl PSomeProtocol for AllowlistMe {} +impl IAllowlistMe for AllowlistMe {} +pub trait IAllowlistMe: Sized + std::ops::Deref { + unsafe fn method(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, method) + } + unsafe fn classMethod() + where + ::Target: objc::Message + Sized, + { + msg_send!(class!(AllowlistMe), classMethod) + } +} +impl AllowlistMe_InterestingCategory for AllowlistMe {} +pub trait AllowlistMe_InterestingCategory: Sized + std::ops::Deref {} diff --git a/bindgen-tests/tests/expectations/tests/objc_blocklist.rs b/bindgen-tests/tests/expectations/tests/objc_blocklist.rs new file mode 100644 index 0000000000..e5c5d2bfd5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_blocklist.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +#[macro_use] +extern crate objc; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct SomeClass(pub id); +impl std::ops::Deref for SomeClass { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for SomeClass {} +impl SomeClass { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(SomeClass), alloc) }) + } +} +impl ISomeClass for SomeClass {} +pub trait ISomeClass: Sized + std::ops::Deref { + unsafe fn ambiguouslyBlockedMethod(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, ambiguouslyBlockedMethod) + } + unsafe fn instanceMethod(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, instanceMethod) + } +} diff --git a/bindgen-tests/tests/expectations/tests/objc_category.rs b/bindgen-tests/tests/expectations/tests/objc_category.rs new file mode 100644 index 0000000000..a1b1e3b1f1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_category.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn method(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, method) + } +} +impl Foo_BarCategory for Foo {} +pub trait Foo_BarCategory: Sized + std::ops::Deref { + unsafe fn categoryMethod(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, categoryMethod) + } +} diff --git a/bindgen-tests/tests/expectations/tests/objc_class.rs b/bindgen-tests/tests/expectations/tests/objc_class.rs new file mode 100644 index 0000000000..a7346d1ee9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_class.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +unsafe extern "C" { + pub static mut fooVar: Foo; +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn method(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, method) + } +} diff --git a/tests/expectations/tests/objc_class_method.rs b/bindgen-tests/tests/expectations/tests/objc_class_method.rs similarity index 76% rename from tests/expectations/tests/objc_class_method.rs rename to bindgen-tests/tests/expectations/tests/objc_class_method.rs index 26f2110f43..6bc2621462 100644 --- a/tests/expectations/tests/objc_class_method.rs +++ b/bindgen-tests/tests/expectations/tests/objc_class_method.rs @@ -1,17 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; +use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -22,7 +15,7 @@ impl std::ops::Deref for Foo { unsafe impl objc::Message for Foo {} impl Foo { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) + Self(unsafe { msg_send!(class!(Foo), alloc) }) } } impl IFoo for Foo {} @@ -37,13 +30,13 @@ pub trait IFoo: Sized + std::ops::Deref { where ::Target: objc::Message + Sized, { - msg_send!(class!(Foo), methodWithInt: foo) + msg_send!(class!(Foo), methodWithInt : foo) } unsafe fn methodWithFoo_(foo: Foo) where ::Target: objc::Message + Sized, { - msg_send!(class!(Foo), methodWithFoo: foo) + msg_send!(class!(Foo), methodWithFoo : foo) } unsafe fn methodReturningInt() -> ::std::os::raw::c_int where @@ -61,9 +54,12 @@ pub trait IFoo: Sized + std::ops::Deref { intvalue: ::std::os::raw::c_int, ptr: *mut ::std::os::raw::c_char, floatvalue: f32, - ) where + ) + where ::Target: objc::Message + Sized, { - msg_send ! (class ! (Foo) , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue) + msg_send!( + class!(Foo), methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue + ) } } diff --git a/bindgen-tests/tests/expectations/tests/objc_escape.rs b/bindgen-tests/tests/expectations/tests/objc_escape.rs new file mode 100644 index 0000000000..1351231d62 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_escape.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct A(pub id); +impl std::ops::Deref for A { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for A {} +impl A { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(A), alloc) }) + } +} +impl IA for A {} +pub trait IA: Sized + std::ops::Deref { + unsafe fn f_as_(&self, arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, f : arg1 r#as : arg2) + } + unsafe fn crate_(&self, self_: ::std::os::raw::c_int) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, crate_ : self_) + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct B(pub id); +impl std::ops::Deref for B { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for B {} +impl B { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(B), alloc) }) + } +} +impl IB for B {} +pub trait IB: Sized + std::ops::Deref { + unsafe fn type_(&self) -> id + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, type) + } + unsafe fn setType_(&self, type_: id) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, setType : type_) + } +} diff --git a/bindgen-tests/tests/expectations/tests/objc_inheritance.rs b/bindgen-tests/tests/expectations/tests/objc_inheritance.rs new file mode 100644 index 0000000000..6fb4e6b857 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_inheritance.rs @@ -0,0 +1,107 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref {} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Bar(pub id); +impl std::ops::Deref for Bar { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Bar {} +impl Bar { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Bar), alloc) }) + } +} +impl IFoo for Bar {} +impl From for Foo { + fn from(child: Bar) -> Foo { + Foo(child.0) + } +} +impl std::convert::TryFrom for Bar { + type Error = &'static str; + fn try_from(parent: Foo) -> Result { + let is_kind_of: bool = unsafe { msg_send!(parent, isKindOfClass : class!(Bar)) }; + if is_kind_of { + Ok(Bar(parent.0)) + } else { + Err("This Foo cannot be downcasted to Bar") + } + } +} +impl IBar for Bar {} +pub trait IBar: Sized + std::ops::Deref {} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Baz(pub id); +impl std::ops::Deref for Baz { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Baz {} +impl Baz { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Baz), alloc) }) + } +} +impl IBar for Baz {} +impl From for Bar { + fn from(child: Baz) -> Bar { + Bar(child.0) + } +} +impl std::convert::TryFrom for Baz { + type Error = &'static str; + fn try_from(parent: Bar) -> Result { + let is_kind_of: bool = unsafe { msg_send!(parent, isKindOfClass : class!(Baz)) }; + if is_kind_of { + Ok(Baz(parent.0)) + } else { + Err("This Bar cannot be downcasted to Baz") + } + } +} +impl IFoo for Baz {} +impl From for Foo { + fn from(child: Baz) -> Foo { + Foo(child.0) + } +} +impl std::convert::TryFrom for Baz { + type Error = &'static str; + fn try_from(parent: Foo) -> Result { + let is_kind_of: bool = unsafe { msg_send!(parent, isKindOfClass : class!(Baz)) }; + if is_kind_of { + Ok(Baz(parent.0)) + } else { + Err("This Foo cannot be downcasted to Baz") + } + } +} +impl IBaz for Baz {} +pub trait IBaz: Sized + std::ops::Deref {} diff --git a/bindgen-tests/tests/expectations/tests/objc_interface.rs b/bindgen-tests/tests/expectations/tests/objc_interface.rs new file mode 100644 index 0000000000..2cc602efd4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_interface.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref {} +pub trait Pbar: Sized + std::ops::Deref {} diff --git a/bindgen-tests/tests/expectations/tests/objc_interface_type.rs b/bindgen-tests/tests/expectations/tests/objc_interface_type.rs new file mode 100644 index 0000000000..56ad75ed25 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_interface_type.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref {} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FooStruct { + pub foo: Foo, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of FooStruct"][::std::mem::size_of::() - 8usize]; + ["Alignment of FooStruct"][::std::mem::align_of::() - 8usize]; + ["Offset of field: FooStruct::foo"][::std::mem::offset_of!(FooStruct, foo) - 0usize]; +}; +impl Default for FooStruct { + 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" { + pub fn fooFunc(foo: Foo); +} +unsafe extern "C" { + pub static mut kFoo: Foo; +} diff --git a/bindgen-tests/tests/expectations/tests/objc_method.rs b/bindgen-tests/tests/expectations/tests/objc_method.rs new file mode 100644 index 0000000000..7d9fd84cf2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_method.rs @@ -0,0 +1,80 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn method(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, method) + } + unsafe fn methodWithInt_(&self, foo: ::std::os::raw::c_int) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, methodWithInt : foo) + } + unsafe fn methodWithFoo_(&self, foo: Foo) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, methodWithFoo : foo) + } + unsafe fn methodReturningInt(&self) -> ::std::os::raw::c_int + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, methodReturningInt) + } + unsafe fn methodReturningFoo(&self) -> Foo + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, methodReturningFoo) + } + unsafe fn methodWithArg1_andArg2_andArg3_( + &self, + intvalue: ::std::os::raw::c_int, + ptr: *mut ::std::os::raw::c_char, + floatvalue: f32, + ) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue) + } + unsafe fn methodWithAndWithoutKeywords_arg2Name__arg4Name_( + &self, + arg1: ::std::os::raw::c_int, + arg2: f32, + arg3: f32, + arg4: ::std::os::raw::c_int, + ) -> instancetype + where + ::Target: objc::Message + Sized, + { + msg_send!( + * self, methodWithAndWithoutKeywords : arg1 arg2Name : arg2 arg3 : arg3 + arg4Name : arg4 + ) + } +} +pub type instancetype = id; diff --git a/bindgen-tests/tests/expectations/tests/objc_method_clash.rs b/bindgen-tests/tests/expectations/tests/objc_method_clash.rs new file mode 100644 index 0000000000..4d35661f8c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_method_clash.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn foo(&self) + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, foo) + } + unsafe fn class_foo() + where + ::Target: objc::Message + Sized, + { + msg_send!(class!(Foo), foo) + } +} diff --git a/tests/expectations/tests/objc_pointer_return_types.rs b/bindgen-tests/tests/expectations/tests/objc_pointer_return_types.rs similarity index 75% rename from tests/expectations/tests/objc_pointer_return_types.rs rename to bindgen-tests/tests/expectations/tests/objc_pointer_return_types.rs index c9b6b52a6b..73c3d6e5c8 100644 --- a/tests/expectations/tests/objc_pointer_return_types.rs +++ b/bindgen-tests/tests/expectations/tests/objc_pointer_return_types.rs @@ -1,17 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; +use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Bar(pub id); impl std::ops::Deref for Bar { type Target = objc::runtime::Object; @@ -22,13 +15,13 @@ impl std::ops::Deref for Bar { unsafe impl objc::Message for Bar {} impl Bar { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Bar), alloc) }) + Self(unsafe { msg_send!(class!(Bar), alloc) }) } } impl IBar for Bar {} pub trait IBar: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -39,7 +32,7 @@ impl std::ops::Deref for Foo { unsafe impl objc::Message for Foo {} impl Foo { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) + Self(unsafe { msg_send!(class!(Foo), alloc) }) } } impl IFoo for Foo {} @@ -48,7 +41,7 @@ pub trait IFoo: Sized + std::ops::Deref { where ::Target: objc::Message + Sized, { - msg_send!(*self, methodUsingBar: my_bar) + msg_send!(* self, methodUsingBar : my_bar) } unsafe fn methodReturningBar() -> Bar where diff --git a/tests/expectations/tests/objc_property_fnptr.rs b/bindgen-tests/tests/expectations/tests/objc_property_fnptr.rs similarity index 78% rename from tests/expectations/tests/objc_property_fnptr.rs rename to bindgen-tests/tests/expectations/tests/objc_property_fnptr.rs index 85f18e9c18..e038edf7f1 100644 --- a/tests/expectations/tests/objc_property_fnptr.rs +++ b/bindgen-tests/tests/expectations/tests/objc_property_fnptr.rs @@ -1,17 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; +use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -22,7 +15,7 @@ impl std::ops::Deref for Foo { unsafe impl objc::Message for Foo {} impl Foo { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) + Self(unsafe { msg_send!(class!(Foo), alloc) }) } } impl IFoo for Foo {} @@ -39,7 +32,7 @@ pub trait IFoo: Sized + std::ops::Deref { where ::Target: objc::Message + Sized, { - msg_send!(*self, func) + msg_send!(* self, func) } unsafe fn setFunc_( &self, @@ -50,9 +43,10 @@ pub trait IFoo: Sized + std::ops::Deref { arg3: f32, ) -> ::std::os::raw::c_int, >, - ) where + ) + where ::Target: objc::Message + Sized, { - msg_send!(*self, setFunc: func) + msg_send!(* self, setFunc : func) } } diff --git a/bindgen-tests/tests/expectations/tests/objc_protocol.rs b/bindgen-tests/tests/expectations/tests/objc_protocol.rs new file mode 100644 index 0000000000..533f5e2ef3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_protocol.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +pub trait PFoo: Sized + std::ops::Deref {} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl PFoo for Foo {} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/objc_protocol_inheritance.rs b/bindgen-tests/tests/expectations/tests/objc_protocol_inheritance.rs similarity index 76% rename from tests/expectations/tests/objc_protocol_inheritance.rs rename to bindgen-tests/tests/expectations/tests/objc_protocol_inheritance.rs index 598273ba35..8bb0ef6f62 100644 --- a/tests/expectations/tests/objc_protocol_inheritance.rs +++ b/bindgen-tests/tests/expectations/tests/objc_protocol_inheritance.rs @@ -1,18 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; +use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; pub trait PFoo: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -23,14 +16,14 @@ impl std::ops::Deref for Foo { unsafe impl objc::Message for Foo {} impl Foo { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) + Self(unsafe { msg_send!(class!(Foo), alloc) }) } } impl PFoo for Foo {} impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone)] +#[derive(Debug, Copy, Clone)] pub struct Bar(pub id); impl std::ops::Deref for Bar { type Target = objc::runtime::Object; @@ -41,7 +34,7 @@ impl std::ops::Deref for Bar { unsafe impl objc::Message for Bar {} impl Bar { pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Bar), alloc) }) + Self(unsafe { msg_send!(class!(Bar), alloc) }) } } impl IFoo for Bar {} @@ -54,8 +47,7 @@ impl From for Foo { impl std::convert::TryFrom for Bar { type Error = &'static str; fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) }; + let is_kind_of: bool = unsafe { msg_send!(parent, isKindOfClass : class!(Bar)) }; if is_kind_of { Ok(Bar(parent.0)) } else { diff --git a/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs b/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs new file mode 100644 index 0000000000..cf38af4e64 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +unsafe extern "C" { + pub static mut object: id; +} +unsafe extern "C" { + pub static mut selector: objc::runtime::Sel; +} +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 new file mode 100644 index 0000000000..1c70009df3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_template.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +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); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn get(&self) -> __BindgenOpaqueArray8<[u8; 8usize]> + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, get) + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct FooMultiGeneric(pub id); +impl std::ops::Deref for FooMultiGeneric { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for FooMultiGeneric {} +impl FooMultiGeneric { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(FooMultiGeneric), alloc) }) + } +} +impl IFooMultiGeneric +for FooMultiGeneric {} +pub trait IFooMultiGeneric< + KeyType: 'static, + ObjectType: 'static, +>: Sized + std::ops::Deref { + unsafe fn objectForKey_( + &self, + key: __BindgenOpaqueArray8<[u8; 8usize]>, + ) -> __BindgenOpaqueArray8<[u8; 8usize]> + where + ::Target: objc::Message + Sized, + { + msg_send!(* self, objectForKey : key) + } +} diff --git a/bindgen-tests/tests/expectations/tests/only_bitfields.rs b/bindgen-tests/tests/expectations/tests/only_bitfields.rs new file mode 100644 index 0000000000..9a73fc2fee --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/only_bitfields.rs @@ -0,0 +1,252 @@ +#![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, Default, Copy, Clone)] +pub struct C { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 1usize]; + ["Alignment of C"][::std::mem::align_of::() - 1usize]; +}; +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/opaque-template-inst-member-2.rs b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member-2.rs new file mode 100644 index 0000000000..14718a9312 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member-2.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** This is like `opaque-template-inst-member.hpp` except exercising the cases + where we are OK to derive Debug/Hash/PartialEq.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OpaqueTemplate { + pub _address: u8, +} +/// Should derive Debug/Hash/PartialEq. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ContainsOpaqueTemplate { + pub mBlah: u32, + pub mBaz: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsOpaqueTemplate", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of ContainsOpaqueTemplate", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContainsOpaqueTemplate::mBlah", + ][::std::mem::offset_of!(ContainsOpaqueTemplate, mBlah) - 0usize]; + [ + "Offset of field: ContainsOpaqueTemplate::mBaz", + ][::std::mem::offset_of!(ContainsOpaqueTemplate, mBaz) - 4usize]; +}; +/// Should also derive Debug/Hash/PartialEq. +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct InheritsOpaqueTemplate { + pub _base: u8, + pub wow: *mut ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of InheritsOpaqueTemplate", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of InheritsOpaqueTemplate", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: InheritsOpaqueTemplate::wow", + ][::std::mem::offset_of!(InheritsOpaqueTemplate, wow) - 8usize]; +}; +impl Default for InheritsOpaqueTemplate { + 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/opaque-template-inst-member.rs b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs new file mode 100644 index 0000000000..f765f01150 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs @@ -0,0 +1,66 @@ +#![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 { + pub _address: u8, +} +/** 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: __BindgenOpaqueArray<[u32; 101usize]>, + pub mBaz: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsOpaqueTemplate", + ][::std::mem::size_of::() - 408usize]; + [ + "Alignment of ContainsOpaqueTemplate", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContainsOpaqueTemplate::mBlah", + ][::std::mem::offset_of!(ContainsOpaqueTemplate, mBlah) - 0usize]; + [ + "Offset of field: ContainsOpaqueTemplate::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: __BindgenOpaqueArray<[u8; 401usize]>, + pub wow: *mut ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of InheritsOpaqueTemplate", + ][::std::mem::size_of::() - 416usize]; + [ + "Alignment of InheritsOpaqueTemplate", + ][::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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/opaque-template-instantiation-namespaced.rs b/bindgen-tests/tests/expectations/tests/opaque-template-instantiation-namespaced.rs new file mode 100644 index 0000000000..58644e053d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque-template-instantiation-namespaced.rs @@ -0,0 +1,101 @@ +#![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 zoidberg { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub struct Template { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, + } + impl Default for Template { + 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, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct Foo { + pub c: ::std::os::raw::c_char, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Foo::c"][::std::mem::offset_of!(Foo, c) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct Bar { + pub i: ::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::i"][::std::mem::offset_of!(Bar, i) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub struct ContainsInstantiation { + pub not_opaque: root::zoidberg::Template, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of ContainsInstantiation", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ContainsInstantiation", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ContainsInstantiation::not_opaque", + ][::std::mem::offset_of!(ContainsInstantiation, not_opaque) - 0usize]; + }; + impl Default for ContainsInstantiation { + 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, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct ContainsOpaqueInstantiation { + pub opaque: u32, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of ContainsOpaqueInstantiation", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of ContainsOpaqueInstantiation", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContainsOpaqueInstantiation::opaque", + ][::std::mem::offset_of!(ContainsOpaqueInstantiation, opaque) - 0usize]; + }; + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of template specialization: Template_open0_Foo_close0", + ][::std::mem::size_of::>() + - 1usize]; + [ + "Align of template specialization: Template_open0_Foo_close0", + ][::std::mem::align_of::>() + - 1usize]; + }; +} diff --git a/bindgen-tests/tests/expectations/tests/opaque-template-instantiation.rs b/bindgen-tests/tests/expectations/tests/opaque-template-instantiation.rs new file mode 100644 index 0000000000..ab68c21856 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque-template-instantiation.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Template { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, +} +impl Default for Template { + 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, Hash, PartialEq, Eq)] +pub struct ContainsInstantiation { + pub not_opaque: Template<::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsInstantiation", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of ContainsInstantiation", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ContainsInstantiation::not_opaque", + ][::std::mem::offset_of!(ContainsInstantiation, not_opaque) - 0usize]; +}; +impl Default for ContainsInstantiation { + 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, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ContainsOpaqueInstantiation { + pub opaque: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsOpaqueInstantiation", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of ContainsOpaqueInstantiation", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContainsOpaqueInstantiation::opaque", + ][::std::mem::offset_of!(ContainsOpaqueInstantiation, opaque) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Template_open0_char_close0", + ][::std::mem::size_of::>() - 1usize]; + [ + "Align of template specialization: Template_open0_char_close0", + ][::std::mem::align_of::>() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/opaque-tracing.rs b/bindgen-tests/tests/expectations/tests/opaque-tracing.rs new file mode 100644 index 0000000000..60d249a88c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque-tracing.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z3fooP9Container"] + pub fn foo(c: *mut Container); +} +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Container { + pub _bindgen_opaque_blob: [u32; 2usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Container"][::std::mem::size_of::() - 8usize]; + ["Alignment of Container"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/opaque_in_struct.rs b/bindgen-tests/tests/expectations/tests/opaque_in_struct.rs new file mode 100644 index 0000000000..b651cd3354 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque_in_struct.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct opaque { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of opaque"][::std::mem::size_of::() - 4usize]; + ["Alignment of opaque"][::std::mem::align_of::() - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct container { + pub contained: opaque, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of container"][::std::mem::size_of::() - 4usize]; + ["Alignment of container"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: container::contained", + ][::std::mem::offset_of!(container, contained) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/opaque_pointer.rs b/bindgen-tests/tests/expectations/tests/opaque_pointer.rs new file mode 100644 index 0000000000..ec519d9c6b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque_pointer.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OtherOpaque { + pub _bindgen_opaque_blob: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of OtherOpaque"][::std::mem::size_of::() - 4usize]; + ["Alignment of OtherOpaque"][::std::mem::align_of::() - 4usize]; +}; +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Opaque { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq)] +pub struct WithOpaquePtr { + pub whatever: *mut u8, + pub other: u32, + pub t: OtherOpaque, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithOpaquePtr"][::std::mem::size_of::() - 16usize]; + ["Alignment of WithOpaquePtr"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: WithOpaquePtr::whatever", + ][::std::mem::offset_of!(WithOpaquePtr, whatever) - 0usize]; + [ + "Offset of field: WithOpaquePtr::other", + ][::std::mem::offset_of!(WithOpaquePtr, other) - 8usize]; + [ + "Offset of field: WithOpaquePtr::t", + ][::std::mem::offset_of!(WithOpaquePtr, t) - 12usize]; +}; +impl Default for WithOpaquePtr { + 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/opaque_typedef.rs b/bindgen-tests/tests/expectations/tests/opaque_typedef.rs new file mode 100644 index 0000000000..90c3b709e3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opaque_typedef.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RandomTemplate { + pub _address: u8, +} +///
+pub type ShouldBeOpaque = u8; +pub type ShouldNotBeOpaque = RandomTemplate; 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 new file mode 100644 index 0000000000..ce5a652d8d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/operator.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z20operator_informationv"] + pub fn operator_information() -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + _unused: [u8; 0], +} 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/ord-enum.rs b/bindgen-tests/tests/expectations/tests/ord-enum.rs new file mode 100644 index 0000000000..aa2e67ab91 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/ord-enum.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum A { + A0 = 0, + A1 = 1, + A2 = 2, + A3 = -1, +} +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum B { + B0 = 1, + B1 = 4, + B2 = 3, + B3 = -1, +} diff --git a/bindgen-tests/tests/expectations/tests/overflowed_enum.rs b/bindgen-tests/tests/expectations/tests/overflowed_enum.rs new file mode 100644 index 0000000000..2c67ba6903 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/overflowed_enum.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Foo { + BAP_ARM = 9698489, + BAP_X86 = 11960045, + BAP_X86_64 = 3128633167, +} +#[repr(u16)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum Bar { + One = 1, + Big = 2, +} diff --git a/bindgen-tests/tests/expectations/tests/overloading.rs b/bindgen-tests/tests/expectations/tests/overloading.rs new file mode 100644 index 0000000000..96504b38eb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/overloading.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z8Evaluatec"] + pub fn Evaluate(r: ::std::os::raw::c_char) -> bool; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z8Evaluateii"] + pub fn Evaluate1(x: ::std::os::raw::c_int, y: ::std::os::raw::c_int) -> bool; +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3foo10MyFunctionEv"] + pub fn foo_MyFunction(); +} +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 new file mode 100644 index 0000000000..b5a734454a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/packed-bitfield.rs @@ -0,0 +1,301 @@ +#![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, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Date { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Date"][::std::mem::size_of::() - 3usize]; + ["Alignment of Date"][::std::mem::align_of::() - 1usize]; +}; +impl Date { + #[inline] + pub fn day(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 5u8) as u8) } + } + #[inline] + pub fn set_day(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 5u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_month(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_year(&mut self, val: ::std::os::raw::c_short) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 15u8, val as u64) + } + } + #[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, + year: ::std::os::raw::c_short, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 5u8, + { + let day: u8 = unsafe { ::std::mem::transmute(day) }; + day as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 5usize, + 4u8, + { + let month: u8 = unsafe { ::std::mem::transmute(month) }; + month as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 9usize, + 15u8, + { + let year: u16 = unsafe { ::std::mem::transmute(year) }; + year as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/packed-n-with-padding.rs b/bindgen-tests/tests/expectations/tests/packed-n-with-padding.rs new file mode 100644 index 0000000000..162a1bebed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/packed-n-with-padding.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C, packed(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct Packed { + pub a: ::std::os::raw::c_char, + pub b: ::std::os::raw::c_short, + pub c: ::std::os::raw::c_char, + pub d: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Packed"][::std::mem::size_of::() - 10usize]; + ["Alignment of Packed"][::std::mem::align_of::() - 2usize]; + ["Offset of field: Packed::a"][::std::mem::offset_of!(Packed, a) - 0usize]; + ["Offset of field: Packed::b"][::std::mem::offset_of!(Packed, b) - 2usize]; + ["Offset of field: Packed::c"][::std::mem::offset_of!(Packed, c) - 4usize]; + ["Offset of field: Packed::d"][::std::mem::offset_of!(Packed, d) - 6usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/packed-vtable.rs b/bindgen-tests/tests/expectations/tests/packed-vtable.rs new file mode 100644 index 0000000000..71e1956d88 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/packed-vtable.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#[repr(C)] +pub struct PackedVtable__bindgen_vtable(::std::os::raw::c_void); +#[repr(C, packed)] +pub struct PackedVtable { + pub vtable_: *const PackedVtable__bindgen_vtable, +} +#[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 { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +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 new file mode 100644 index 0000000000..6dee4ec7d5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/parm-union.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Struct { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Struct"][::std::mem::size_of::() - 1usize]; + ["Alignment of Struct"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN6Struct8FunctionER5Union"] + pub fn Struct_Function(this: *mut Struct, arg1: *mut Union); +} +impl Struct { + #[inline] + pub unsafe fn Function(&mut self, arg1: *mut Union) { + Struct_Function(self, arg1) + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Union { + _unused: [u8; 0], +} diff --git a/bindgen-tests/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs b/bindgen-tests/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs new file mode 100644 index 0000000000..98c10d7ec5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs @@ -0,0 +1,3 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const RENAMED_MyVal: _bindgen_ty_1 = 0; +pub type _bindgen_ty_1 = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs b/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs new file mode 100644 index 0000000000..cba5cfbb52 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs @@ -0,0 +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)] +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 { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Derived { + pub b: bool, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Usage { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN5Usage13static_memberE"] + pub static mut Usage_static_member: __BindgenOpaqueArray<[u32; 2usize]>; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Usage"][::std::mem::size_of::() - 1usize]; + ["Alignment of Usage"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/pointer-attr.rs b/bindgen-tests/tests/expectations/tests/pointer-attr.rs new file mode 100644 index 0000000000..4d7e250b9c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/pointer-attr.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..cb1ebfa4f7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/prefix-link-name-c.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..07cacc5f7a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/prefix-link-name-cpp.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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/prepend-enum-constified-variant.rs b/bindgen-tests/tests/expectations/tests/prepend-enum-constified-variant.rs new file mode 100644 index 0000000000..ff49d684f1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/prepend-enum-constified-variant.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +impl AVCodecID { + pub const AV_CODEC_ID_TTF: AVCodecID = AVCodecID::AV_CODEC_ID_FIRST_UNKNOWN; +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum AVCodecID { + AV_CODEC_ID_FIRST_UNKNOWN = 98304, +} diff --git a/bindgen-tests/tests/expectations/tests/prepend_enum_name.rs b/bindgen-tests/tests/expectations/tests/prepend_enum_name.rs new file mode 100644 index 0000000000..b4201a8cd9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/prepend_enum_name.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const FOO_BAR: foo = 0; +pub const FOO_BAZ: foo = 1; +pub type foo = ::std::os::raw::c_uint; diff --git a/bindgen-tests/tests/expectations/tests/private.rs b/bindgen-tests/tests/expectations/tests/private.rs new file mode 100644 index 0000000000..bf1e853e6a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/private.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct HasPrivate { + pub mNotPrivate: ::std::os::raw::c_int, + ///
+ mIsPrivate: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of HasPrivate"][::std::mem::size_of::() - 8usize]; + ["Alignment of HasPrivate"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: HasPrivate::mNotPrivate", + ][::std::mem::offset_of!(HasPrivate, mNotPrivate) - 0usize]; + [ + "Offset of field: HasPrivate::mIsPrivate", + ][::std::mem::offset_of!(HasPrivate, mIsPrivate) - 4usize]; +}; +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct VeryPrivate { + mIsPrivate: ::std::os::raw::c_int, + mIsAlsoPrivate: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of VeryPrivate"][::std::mem::size_of::() - 8usize]; + ["Alignment of VeryPrivate"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: VeryPrivate::mIsPrivate", + ][::std::mem::offset_of!(VeryPrivate, mIsPrivate) - 0usize]; + [ + "Offset of field: VeryPrivate::mIsAlsoPrivate", + ][::std::mem::offset_of!(VeryPrivate, mIsAlsoPrivate) - 4usize]; +}; +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ContradictPrivate { + ///
+ pub mNotPrivate: ::std::os::raw::c_int, + mIsPrivate: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ContradictPrivate"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of ContradictPrivate", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ContradictPrivate::mNotPrivate", + ][::std::mem::offset_of!(ContradictPrivate, mNotPrivate) - 0usize]; + [ + "Offset of field: ContradictPrivate::mIsPrivate", + ][::std::mem::offset_of!(ContradictPrivate, mIsPrivate) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/private_fields.rs b/bindgen-tests/tests/expectations/tests/private_fields.rs new file mode 100644 index 0000000000..abb2886d39 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/private_fields.rs @@ -0,0 +1,788 @@ +#![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, Default, Copy, Clone)] +pub struct PubPriv { + pub x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PubPriv"][::std::mem::size_of::() - 8usize]; + ["Alignment of PubPriv"][::std::mem::align_of::() - 4usize]; + ["Offset of field: PubPriv::x"][::std::mem::offset_of!(PubPriv, x) - 0usize]; + ["Offset of field: PubPriv::y"][::std::mem::offset_of!(PubPriv, y) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct PrivateBitFields { + pub _bindgen_align: [u32; 0], + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PrivateBitFields"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of PrivateBitFields", + ][::std::mem::align_of::() - 4usize]; +}; +impl PrivateBitFields { + #[inline] + fn a(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + fn set_a(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_b(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct PublicBitFields { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PublicBitFields"][::std::mem::size_of::() - 4usize]; + ["Alignment of PublicBitFields"][::std::mem::align_of::() - 4usize]; +}; +impl PublicBitFields { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct MixedBitFields { + pub _bindgen_align: [u32; 0], + _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of MixedBitFields"][::std::mem::size_of::() - 4usize]; + ["Alignment of MixedBitFields"][::std::mem::align_of::() - 4usize]; +}; +impl MixedBitFields { + #[inline] + fn a(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + fn set_a(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_d(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let d: u32 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Base { + pub member: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Base"][::std::mem::size_of::() - 4usize]; + ["Alignment of Base"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Base::member"][::std::mem::offset_of!(Base, member) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct InheritsPrivately { + _base: Base, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of InheritsPrivately"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of InheritsPrivately", + ][::std::mem::align_of::() - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct InheritsPublically { + pub _base: Base, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of InheritsPublically"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of InheritsPublically", + ][::std::mem::align_of::() - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithAnonStruct { + __bindgen_anon_1: WithAnonStruct__bindgen_ty_1, + pub __bindgen_anon_2: WithAnonStruct__bindgen_ty_2, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithAnonStruct__bindgen_ty_1 { + pub a: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of WithAnonStruct__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WithAnonStruct__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithAnonStruct__bindgen_ty_1::a", + ][::std::mem::offset_of!(WithAnonStruct__bindgen_ty_1, a) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithAnonStruct__bindgen_ty_2 { + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of WithAnonStruct__bindgen_ty_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WithAnonStruct__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithAnonStruct__bindgen_ty_2::b", + ][::std::mem::offset_of!(WithAnonStruct__bindgen_ty_2, b) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithAnonStruct"][::std::mem::size_of::() - 8usize]; + ["Alignment of WithAnonStruct"][::std::mem::align_of::() - 4usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct WithAnonUnion { + __bindgen_anon_1: WithAnonUnion__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union WithAnonUnion__bindgen_ty_1 { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of WithAnonUnion__bindgen_ty_1", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of WithAnonUnion__bindgen_ty_1", + ][::std::mem::align_of::() - 1usize]; +}; +impl Default for WithAnonUnion__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithAnonUnion"][::std::mem::size_of::() - 1usize]; + ["Alignment of WithAnonUnion"][::std::mem::align_of::() - 1usize]; +}; +impl Default for WithAnonUnion { + 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, Default, Copy, Clone)] +pub struct Override { + pub a: ::std::os::raw::c_uint, + ///
+ b: ::std::os::raw::c_uint, + private_c: ::std::os::raw::c_uint, + _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub __bindgen_padding_0: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Override"][::std::mem::size_of::() - 16usize]; + ["Alignment of Override"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Override::a"][::std::mem::offset_of!(Override, a) - 0usize]; + ["Offset of field: Override::b"][::std::mem::offset_of!(Override, b) - 4usize]; + [ + "Offset of field: Override::private_c", + ][::std::mem::offset_of!(Override, private_c) - 8usize]; +}; +impl Override { + #[inline] + pub fn bf_a(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + pub fn set_bf_a(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_bf_b(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[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) } + } + #[inline] + fn set_private_bf_c(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 4u8, val as u64) + } + } + #[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, + private_bf_c: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let bf_a: u32 = unsafe { ::std::mem::transmute(bf_a) }; + bf_a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let bf_b: u32 = unsafe { ::std::mem::transmute(bf_b) }; + bf_b as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 4u8, + { + let private_bf_c: u32 = unsafe { + ::std::mem::transmute(private_bf_c) + }; + private_bf_c as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/ptr32-has-different-size.rs b/bindgen-tests/tests/expectations/tests/ptr32-has-different-size.rs new file mode 100644 index 0000000000..f4f3ab4294 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/ptr32-has-different-size.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TEST_STRUCT { + pub ptr_32bit: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TEST_STRUCT"][::std::mem::size_of::() - 4usize]; + ["Alignment of TEST_STRUCT"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: TEST_STRUCT::ptr_32bit", + ][::std::mem::offset_of!(TEST_STRUCT, ptr_32bit) - 0usize]; +}; +impl Default for TEST_STRUCT { + 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 type TEST = TEST_STRUCT; diff --git a/bindgen-tests/tests/expectations/tests/public-dtor.rs b/bindgen-tests/tests/expectations/tests/public-dtor.rs new file mode 100644 index 0000000000..578d3e76a5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/public-dtor.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct cv_Foo { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cv_Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of cv_Foo"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN2cv3FooD1Ev"] + pub fn cv_Foo_Foo_destructor(this: *mut cv_Foo); +} +impl cv_Foo { + #[inline] + pub unsafe fn destruct(&mut self) { + cv_Foo_Foo_destructor(self) + } +} +#[repr(C)] +#[derive(Debug, Default)] +pub struct cv_Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cv_Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of cv_Bar"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/qualified-dependent-types.rs b/bindgen-tests/tests/expectations/tests/qualified-dependent-types.rs new file mode 100644 index 0000000000..9bbbddd88d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/qualified-dependent-types.rs @@ -0,0 +1,11 @@ +#![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, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/redeclaration.rs b/bindgen-tests/tests/expectations/tests/redeclaration.rs new file mode 100644 index 0000000000..736d379f01 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/redeclaration.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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 new file mode 100644 index 0000000000..05401e52ca --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/redundant-packed-and-align.rs @@ -0,0 +1,372 @@ +#![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)] +#[repr(align(8))] +#[derive(Debug, Default, Copy, Clone)] +pub struct redundant_packed { + pub a: u32, + pub b: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of redundant_packed"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of redundant_packed", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: redundant_packed::a", + ][::std::mem::offset_of!(redundant_packed, a) - 0usize]; + [ + "Offset of field: redundant_packed::b", + ][::std::mem::offset_of!(redundant_packed, b) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct redundant_packed_bitfield { + pub _bindgen_align: [u64; 0], + pub a: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub c: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of redundant_packed_bitfield", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of redundant_packed_bitfield", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: redundant_packed_bitfield::a", + ][::std::mem::offset_of!(redundant_packed_bitfield, a) - 0usize]; + [ + "Offset of field: redundant_packed_bitfield::c", + ][::std::mem::offset_of!(redundant_packed_bitfield, c) - 4usize]; +}; +impl redundant_packed_bitfield { + #[inline] + pub fn b0(&self) -> u8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_b0(&mut self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b1(&mut self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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 + .set( + 0usize, + 1u8, + { + let b0: u8 = unsafe { ::std::mem::transmute(b0) }; + b0 as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b1: u8 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub union redundant_packed_union { + pub a: u64, + pub b: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of redundant_packed_union", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of redundant_packed_union", + ][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: redundant_packed_union::a", + ][::std::mem::offset_of!(redundant_packed_union, a) - 0usize]; + [ + "Offset of field: redundant_packed_union::b", + ][::std::mem::offset_of!(redundant_packed_union, b) - 0usize]; +}; +impl Default for redundant_packed_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() + } + } +} +#[repr(C)] +#[repr(align(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct inner { + pub a: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of inner"][::std::mem::size_of::() - 2usize]; + ["Alignment of inner"][::std::mem::align_of::() - 2usize]; + ["Offset of field: inner::a"][::std::mem::offset_of!(inner, a) - 0usize]; +}; +#[repr(C)] +#[repr(align(8))] +#[derive(Debug, Default, Copy, Clone)] +pub struct outer_redundant_packed { + pub a: [inner; 2usize], + pub b: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of outer_redundant_packed", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of outer_redundant_packed", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: outer_redundant_packed::a", + ][::std::mem::offset_of!(outer_redundant_packed, a) - 0usize]; + [ + "Offset of field: outer_redundant_packed::b", + ][::std::mem::offset_of!(outer_redundant_packed, b) - 4usize]; +}; +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone)] +pub struct redundant_pragma_packed { + pub a: u8, + pub b: u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of redundant_pragma_packed", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of redundant_pragma_packed", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: redundant_pragma_packed::a", + ][::std::mem::offset_of!(redundant_pragma_packed, a) - 0usize]; + [ + "Offset of field: redundant_pragma_packed::b", + ][::std::mem::offset_of!(redundant_pragma_packed, b) - 2usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/ref_argument_array.rs b/bindgen-tests/tests/expectations/tests/ref_argument_array.rs new file mode 100644 index 0000000000..4928a185fe --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/ref_argument_array.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const NSID_LENGTH: u32 = 10; +#[repr(C)] +pub struct nsID__bindgen_vtable { + pub nsID_ToProvidedString: unsafe extern "C" fn( + this: *mut nsID, + aDest: *mut [::std::os::raw::c_char; 10usize], + ), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct nsID { + pub vtable_: *const nsID__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsID"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsID"][::std::mem::align_of::() - 8usize]; +}; +impl Default for nsID { + 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}_ZN4nsID16ToProvidedStringERA10_c"] + pub fn nsID_ToProvidedString( + this: *mut ::std::os::raw::c_void, + aDest: *mut [::std::os::raw::c_char; 10usize], + ); +} 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/reparented_replacement.rs b/bindgen-tests/tests/expectations/tests/reparented_replacement.rs new file mode 100644 index 0000000000..9b2cc33ce9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/reparented_replacement.rs @@ -0,0 +1,23 @@ +#![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 foo { + #[allow(unused_imports)] + use self::super::super::root; + ///
+ #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Bar { + pub bazz: ::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::bazz"][::std::mem::offset_of!(Bar, bazz) - 0usize]; + }; + } + pub type ReferencesBar = root::foo::Bar; +} diff --git a/bindgen-tests/tests/expectations/tests/replace_template_alias.rs b/bindgen-tests/tests/expectations/tests/replace_template_alias.rs new file mode 100644 index 0000000000..2efa164ddf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/replace_template_alias.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** But the replacement type does use T! + +
*/ +pub type JS_detail_MaybeWrapped = T; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct JS_Rooted { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: JS_detail_MaybeWrapped, +} +impl Default for JS_Rooted { + 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/replace_use.rs b/bindgen-tests/tests/expectations/tests/replace_use.rs new file mode 100644 index 0000000000..ebf9657176 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/replace_use.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +///
+#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct nsTArray { + pub y: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test { + pub a: nsTArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 4usize]; + ["Alignment of Test"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Test::a"][::std::mem::offset_of!(Test, a) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: nsTArray_open0_long_close0", + ][::std::mem::size_of::() - 4usize]; + [ + "Align of template specialization: nsTArray_open0_long_close0", + ][::std::mem::align_of::() - 4usize]; +}; diff --git a/tests/expectations/tests/replaces_double.rs b/bindgen-tests/tests/expectations/tests/replaces_double.rs similarity index 90% rename from tests/expectations/tests/replaces_double.rs rename to bindgen-tests/tests/expectations/tests/replaces_double.rs index 99de132090..e764113f21 100644 --- a/tests/expectations/tests/replaces_double.rs +++ b/bindgen-tests/tests/expectations/tests/replaces_double.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Wrapper_Wrapped { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } impl Default for Wrapper_Wrapped { fn default() -> Self { @@ -24,8 +18,8 @@ pub type Wrapper_Type = Wrapper_Wrapped; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Rooted { - pub ptr: Rooted_MaybeWrapped, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: Rooted_MaybeWrapped, } ///
pub type Rooted_MaybeWrapped = T; diff --git a/bindgen-tests/tests/expectations/tests/repr-align.rs b/bindgen-tests/tests/expectations/tests/repr-align.rs new file mode 100644 index 0000000000..867a28cc78 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/repr-align.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#[repr(C)] +#[repr(align(8))] +#[derive(Debug, Default, Copy, Clone)] +pub struct a { + pub b: ::std::os::raw::c_int, + pub c: ::std::os::raw::c_int, +} +#[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)] +pub struct b { + pub b: ::std::os::raw::c_int, + pub c: ::std::os::raw::c_int, +} +#[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 new file mode 100644 index 0000000000..cfbab6b968 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/resolved_type_def_function.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type FuncType = ::std::option::Option; +unsafe extern "C" { + pub fn Func(); +} diff --git a/bindgen-tests/tests/expectations/tests/same_struct_name_in_different_namespaces.rs b/bindgen-tests/tests/expectations/tests/same_struct_name_in_different_namespaces.rs new file mode 100644 index 0000000000..e6e4088abf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/same_struct_name_in_different_namespaces.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct JS_Zone { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct JS_shadow_Zone { + pub x: ::std::os::raw::c_int, + pub y: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of JS_shadow_Zone"][::std::mem::size_of::() - 8usize]; + ["Alignment of JS_shadow_Zone"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: JS_shadow_Zone::x", + ][::std::mem::offset_of!(JS_shadow_Zone, x) - 0usize]; + [ + "Offset of field: JS_shadow_Zone::y", + ][::std::mem::offset_of!(JS_shadow_Zone, y) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/sentry-defined-multiple-times.rs b/bindgen-tests/tests/expectations/tests/sentry-defined-multiple-times.rs new file mode 100644 index 0000000000..0fe153e700 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/sentry-defined-multiple-times.rs @@ -0,0 +1,235 @@ +#![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 whatever { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Wrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Wrapper_sentry { + pub i_am_wrapper_sentry: ::std::os::raw::c_int, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct sentry { + pub i_am_plain_sentry: bool, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of sentry"][::std::mem::size_of::() - 1usize]; + ["Alignment of sentry"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: sentry::i_am_plain_sentry", + ][::std::mem::offset_of!(sentry, i_am_plain_sentry) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct NotTemplateWrapper { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of NotTemplateWrapper", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of NotTemplateWrapper", + ][::std::mem::align_of::() - 1usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct NotTemplateWrapper_sentry { + pub i_am_not_template_wrapper_sentry: ::std::os::raw::c_char, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of NotTemplateWrapper_sentry", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of NotTemplateWrapper_sentry", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: NotTemplateWrapper_sentry::i_am_not_template_wrapper_sentry", + ][::std::mem::offset_of!( + NotTemplateWrapper_sentry, i_am_not_template_wrapper_sentry + ) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct InlineNotTemplateWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct InlineNotTemplateWrapper_sentry { + pub i_am_inline_not_template_wrapper_sentry: bool, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of InlineNotTemplateWrapper_sentry", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of InlineNotTemplateWrapper_sentry", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: InlineNotTemplateWrapper_sentry::i_am_inline_not_template_wrapper_sentry", + ][::std::mem::offset_of!( + InlineNotTemplateWrapper_sentry, i_am_inline_not_template_wrapper_sentry + ) - 0usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of InlineNotTemplateWrapper", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of InlineNotTemplateWrapper", + ][::std::mem::align_of::() - 1usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct InlineTemplateWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct InlineTemplateWrapper_sentry { + pub i_am_inline_template_wrapper_sentry: ::std::os::raw::c_int, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleWrapper_InnerDoubleWrapper { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleWrapper_InnerDoubleWrapper", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of OuterDoubleWrapper_InnerDoubleWrapper", + ][::std::mem::align_of::() - 1usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleWrapper", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of OuterDoubleWrapper", + ][::std::mem::align_of::() - 1usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleWrapper_InnerDoubleWrapper_sentry { + pub i_am_double_wrapper_sentry: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleWrapper_InnerDoubleWrapper_sentry", + ][::std::mem::size_of::() + - 4usize]; + [ + "Alignment of OuterDoubleWrapper_InnerDoubleWrapper_sentry", + ][::std::mem::align_of::() + - 4usize]; + [ + "Offset of field: OuterDoubleWrapper_InnerDoubleWrapper_sentry::i_am_double_wrapper_sentry", + ][::std::mem::offset_of!( + OuterDoubleWrapper_InnerDoubleWrapper_sentry, i_am_double_wrapper_sentry + ) - 0usize]; + }; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleInlineWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleInlineWrapper_InnerDoubleInlineWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry { + pub i_am_double_wrapper_inline_sentry: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry", + ][::std::mem::size_of::< + OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry, + >() - 4usize]; + [ + "Alignment of OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry", + ][::std::mem::align_of::< + OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry, + >() - 4usize]; + [ + "Offset of field: OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry::i_am_double_wrapper_inline_sentry", + ][::std::mem::offset_of!( + OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry, + i_am_double_wrapper_inline_sentry + ) - 0usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleInlineWrapper_InnerDoubleInlineWrapper", + ][::std::mem::size_of::() + - 1usize]; + [ + "Alignment of OuterDoubleInlineWrapper_InnerDoubleInlineWrapper", + ][::std::mem::align_of::() + - 1usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [ + "Size of OuterDoubleInlineWrapper", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of OuterDoubleInlineWrapper", + ][::std::mem::align_of::() - 1usize]; + }; + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OutsideNamespaceWrapper { + pub _address: u8, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct OutsideNamespaceWrapper_sentry { + pub i_am_outside_namespace_wrapper_sentry: ::std::os::raw::c_int, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct sentry { + pub i_am_outside_namespace_sentry: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of sentry"][::std::mem::size_of::() - 4usize]; + ["Alignment of sentry"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: sentry::i_am_outside_namespace_sentry", + ][::std::mem::offset_of!(sentry, i_am_outside_namespace_sentry) - 0usize]; + }; +} diff --git a/tests/expectations/tests/short-enums.rs b/bindgen-tests/tests/expectations/tests/short-enums.rs similarity index 77% rename from tests/expectations/tests/short-enums.rs rename to bindgen-tests/tests/expectations/tests/short-enums.rs index a8a494eaa6..493bb5b419 100644 --- a/tests/expectations/tests/short-enums.rs +++ b/bindgen-tests/tests/expectations/tests/short-enums.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum one_byte_t { diff --git a/bindgen-tests/tests/expectations/tests/size_t_template.rs b/bindgen-tests/tests/expectations/tests/size_t_template.rs new file mode 100644 index 0000000000..08ffa22750 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/size_t_template.rs @@ -0,0 +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 __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: __BindgenOpaqueArray<[u32; 3usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 12usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::arr"][::std::mem::offset_of!(C, arr) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/sort-items.rs b/bindgen-tests/tests/expectations/tests/sort-items.rs new file mode 100644 index 0000000000..e04e3b6090 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/sort-items.rs @@ -0,0 +1,220 @@ +#![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 { + pub type number = ::std::os::raw::c_int; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: root::number, + pub y: root::number, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Angle { + pub a: root::number, + pub b: root::number, + } + pub const NUMBER: root::number = 42; + #[test] + fn bindgen_test_layout_Point() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Point)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(Point)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Point), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(Point), + "::", + stringify!(y) + ) + ); + } + #[test] + fn bindgen_test_layout_Angle() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Angle)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(Angle)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Angle), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(Angle), + "::", + stringify!(b) + ) + ); + } + pub mod ns { + pub type number = ::std::os::raw::c_int; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: root::ns::number, + pub y: root::ns::number, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Angle { + pub a: root::ns::number, + pub b: root::ns::number, + } + pub const NUMBER: root::ns::number = 42; + #[test] + fn bindgen_test_layout_Point() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Point)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(Point)) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Point), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(Point), + "::", + stringify!(y) + ) + ); + } + #[test] + fn bindgen_test_layout_Angle() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Angle)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(Angle)) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Angle), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(Angle), + "::", + stringify!(b) + ) + ); + } + #[allow(unused_imports)] + use self::super::super::root; + extern "C" { + #[link_name = "\u{1}_ZN2ns3fooEv"] + pub fn foo() -> ::std::os::raw::c_int; + } + extern "C" { + #[link_name = "\u{1}_ZN2ns3barEi"] + pub fn bar(x: root::ns::number) -> ::std::os::raw::c_int; + } + 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" { + #[link_name = "\u{1}_Z3foov"] + pub fn foo() -> ::std::os::raw::c_int; + } + extern "C" { + #[link_name = "\u{1}_Z3bari"] + pub fn bar(x: root::number) -> ::std::os::raw::c_int; + } + 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/sorted_items.rs b/bindgen-tests/tests/expectations/tests/sorted_items.rs new file mode 100644 index 0000000000..1c235fb31d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/sorted_items.rs @@ -0,0 +1,90 @@ +#![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 { + pub type number = ::std::os::raw::c_int; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: root::number, + pub y: root::number, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Angle { + pub a: root::number, + pub b: root::number, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Point"][::std::mem::size_of::() - 8usize]; + ["Alignment of Point"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Point::x"][::std::mem::offset_of!(Point, x) - 0usize]; + ["Offset of field: Point::y"][::std::mem::offset_of!(Point, y) - 4usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Angle"][::std::mem::size_of::() - 8usize]; + ["Alignment of Angle"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Angle::a"][::std::mem::offset_of!(Angle, a) - 0usize]; + ["Offset of field: Angle::b"][::std::mem::offset_of!(Angle, b) - 4usize]; + }; + pub const NUMBER: root::number = 42; + pub mod ns { + pub type number = ::std::os::raw::c_int; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: root::ns::number, + pub y: root::ns::number, + } + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Angle { + pub a: root::ns::number, + pub b: root::ns::number, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Point"][::std::mem::size_of::() - 8usize]; + ["Alignment of Point"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Point::x"][::std::mem::offset_of!(Point, x) - 0usize]; + ["Offset of field: Point::y"][::std::mem::offset_of!(Point, y) - 4usize]; + }; + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Angle"][::std::mem::size_of::() - 8usize]; + ["Alignment of Angle"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Angle::a"][::std::mem::offset_of!(Angle, a) - 0usize]; + ["Offset of field: Angle::b"][::std::mem::offset_of!(Angle, b) - 4usize]; + }; + pub const NUMBER: root::ns::number = 42; + #[allow(unused_imports)] + use self::super::super::root; + unsafe extern "C" { + #[link_name = "\u{1}_ZN2ns3fooEv"] + pub fn foo() -> ::std::os::raw::c_int; + } + unsafe extern "C" { + #[link_name = "\u{1}_ZN2ns3barEi"] + pub fn bar(x: root::ns::number) -> ::std::os::raw::c_int; + } + 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; + unsafe extern "C" { + #[link_name = "\u{1}_Z3foov"] + pub fn foo() -> ::std::os::raw::c_int; + } + unsafe extern "C" { + #[link_name = "\u{1}_Z3bari"] + pub fn bar(x: root::number) -> ::std::os::raw::c_int; + } + 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 new file mode 100644 index 0000000000..7cb1a2a8fb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/stdint_typedef.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn fun() -> u64; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Struct { + pub field: u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Struct"][::std::mem::size_of::() - 8usize]; + ["Alignment of Struct"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Struct::field"][::std::mem::offset_of!(Struct, field) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/strings_array.rs b/bindgen-tests/tests/expectations/tests/strings_array.rs new file mode 100644 index 0000000000..12543e59a8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/strings_array.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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_cstr.rs b/bindgen-tests/tests/expectations/tests/strings_cstr.rs new file mode 100644 index 0000000000..ca089cf130 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/strings_cstr.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/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_containing_forward_declared_struct.rs b/bindgen-tests/tests/expectations/tests/struct_containing_forward_declared_struct.rs new file mode 100644 index 0000000000..0fe9024a5f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_containing_forward_declared_struct.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct a { + pub val_a: *mut b, +} +#[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::val_a"][::std::mem::offset_of!(a, val_a) - 0usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct b { + pub val_b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of b"][::std::mem::size_of::() - 4usize]; + ["Alignment of b"][::std::mem::align_of::() - 4usize]; + ["Offset of field: b::val_b"][::std::mem::offset_of!(b, val_b) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_typedef.rs b/bindgen-tests/tests/expectations/tests/struct_typedef.rs new file mode 100644 index 0000000000..bc12a1bce8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_typedef.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct typedef_named_struct { + pub has_name: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of typedef_named_struct", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of typedef_named_struct", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: typedef_named_struct::has_name", + ][::std::mem::offset_of!(typedef_named_struct, has_name) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct _bindgen_ty_1 { + pub no_name: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 8usize]; + ["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 8usize]; + [ + "Offset of field: _bindgen_ty_1::no_name", + ][::std::mem::offset_of!(_bindgen_ty_1, no_name) - 0usize]; +}; +impl Default for _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() + } + } +} +pub type struct_ptr_t = *mut _bindgen_ty_1; +pub type struct_ptr_ptr_t = *mut *mut _bindgen_ty_1; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum typedef_named_enum { + ENUM_HAS_NAME = 1, +} +pub const ENUM_IS_ANON: _bindgen_ty_2 = _bindgen_ty_2::ENUM_IS_ANON; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_2 { + ENUM_IS_ANON = 0, +} +pub type enum_ptr_t = *mut _bindgen_ty_2; +pub type enum_ptr_ptr_t = *mut *mut _bindgen_ty_2; diff --git a/bindgen-tests/tests/expectations/tests/struct_typedef_ns.rs b/bindgen-tests/tests/expectations/tests/struct_typedef_ns.rs new file mode 100644 index 0000000000..82f93dfd16 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_typedef_ns.rs @@ -0,0 +1,54 @@ +#![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 whatever { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct typedef_struct { + pub foo: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of typedef_struct"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of typedef_struct", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: typedef_struct::foo", + ][::std::mem::offset_of!(typedef_struct, foo) - 0usize]; + }; + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum typedef_enum { + BAR = 1, + } + } + pub mod _bindgen_mod_id_12 { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] + pub struct typedef_struct { + pub foo: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of typedef_struct"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of typedef_struct", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: typedef_struct::foo", + ][::std::mem::offset_of!(typedef_struct, foo) - 0usize]; + }; + #[repr(u32)] + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub enum typedef_enum { + BAR = 1, + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_struct.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct.rs new file mode 100644 index 0000000000..51aa19c572 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_int, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_array.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_array.rs new file mode 100644 index 0000000000..930e6b9aba --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_array.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub bar: [foo__bindgen_ty_1; 2usize], + pub baz: [[[foo__bindgen_ty_2; 4usize]; 3usize]; 2usize], +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_int, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_2 { + pub a: ::std::os::raw::c_int, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_2"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_2", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_2::a", + ][::std::mem::offset_of!(foo__bindgen_ty_2, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_2::b", + ][::std::mem::offset_of!(foo__bindgen_ty_2, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 208usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; + ["Offset of field: foo::baz"][::std::mem::offset_of!(foo, baz) - 16usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_pointer.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_pointer.rs new file mode 100644 index 0000000000..6bdee34590 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_struct_pointer.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub bar: *mut foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_int, + pub b: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_union.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_union.rs new file mode 100644 index 0000000000..6520163259 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_union.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_struct.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_struct.rs new file mode 100644 index 0000000000..29cf382e5f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_struct.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union.rs new file mode 100644 index 0000000000..2f95e0f5e0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct foo { + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs new file mode 100644 index 0000000000..a294c871d3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs @@ -0,0 +1,450 @@ +#![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, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct bitfield { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub e: ::std::os::raw::c_int, + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 8usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bitfield"][::std::mem::size_of::() - 16usize]; + ["Alignment of bitfield"][::std::mem::align_of::() - 4usize]; + ["Offset of field: bitfield::e"][::std::mem::offset_of!(bitfield, e) - 4usize]; +}; +impl bitfield { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_c(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 2u8, val as u64) + } + } + #[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, + c: ::std::os::raw::c_ushort, + d: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let a: u16 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 1u8, + { + let b: u16 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 2usize, + 1u8, + { + let c: u16 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 6usize, + 2u8, + { + let d: u16 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub fn f(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 2u8) as u32) } + } + #[inline] + pub fn set_f(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 2u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_g(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(32usize, 32u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 8usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 2u8, + { + let f: u32 = unsafe { ::std::mem::transmute(f) }; + f as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 32usize, + 32u8, + { + let g: u32 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs b/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs new file mode 100644 index 0000000000..f86fe6fb8f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct LittleArray { + pub a: [::std::os::raw::c_int; 32usize], +} +#[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(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct BigArray { + pub a: [::std::os::raw::c_int; 33usize], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct WithLittleArray { + pub a: LittleArray, +} +#[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(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct WithBigArray { + pub a: BigArray, +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs b/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs new file mode 100644 index 0000000000..df7a2192ed --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct S { + pub large_array: [::std::os::raw::c_char; 33usize], +} +#[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(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct ST { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub large_array: [T; 33usize], +} +impl Default for ST { + 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/struct_with_nesting.rs b/bindgen-tests/tests/expectations/tests/struct_with_nesting.rs new file mode 100644 index 0000000000..369384e88c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_nesting.rs @@ -0,0 +1,98 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct foo { + pub a: ::std::os::raw::c_uint, + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub b: ::std::os::raw::c_uint, + 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, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of foo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::c1", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_1, c1) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::c2", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_1, c2) - 2usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of foo__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d1", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, d1) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d2", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, d2) - 1usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d3", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, d3) - 2usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d4", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, d4) - 3usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::a"][::std::mem::offset_of!(foo, a) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_packing.rs b/bindgen-tests/tests/expectations/tests/struct_with_packing.rs new file mode 100644 index 0000000000..2687f9750b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_packing.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct a { + pub b: ::std::os::raw::c_char, + pub c: ::std::os::raw::c_short, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of a"][::std::mem::size_of::() - 3usize]; + ["Alignment of a"][::std::mem::align_of::() - 1usize]; + ["Offset of field: a::b"][::std::mem::offset_of!(a, b) - 0usize]; + ["Offset of field: a::c"][::std::mem::offset_of!(a, c) - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_struct.rs b/bindgen-tests/tests/expectations/tests/struct_with_struct.rs new file mode 100644 index 0000000000..40c3972600 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_struct.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub x: ::std::os::raw::c_uint, + pub y: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::x", + ][::std::mem::offset_of!(foo__bindgen_ty_1, x) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::y", + ][::std::mem::offset_of!(foo__bindgen_ty_1, y) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_typedef_template_arg.rs b/bindgen-tests/tests/expectations/tests/struct_with_typedef_template_arg.rs new file mode 100644 index 0000000000..2aaae12dcf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/struct_with_typedef_template_arg.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Proxy { + pub _address: u8, +} +pub type Proxy_foo = ::std::option::Option; diff --git a/bindgen-tests/tests/expectations/tests/template-fun-ty.rs b/bindgen-tests/tests/expectations/tests/template-fun-ty.rs new file mode 100644 index 0000000000..5337af037a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template-fun-ty.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Foo { + pub _address: u8, +} +pub type Foo_FunctionPtr = ::std::option::Option T>; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RefPtr { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RefPtr_Proxy { + pub _address: u8, +} +pub type RefPtr_Proxy_member_function = ::std::option::Option< + unsafe extern "C" fn(arg1: Args) -> R, +>; +pub type Returner = ::std::option::Option T>; diff --git a/tests/expectations/tests/template-param-usage-0.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-0.rs similarity index 80% rename from tests/expectations/tests/template-param-usage-0.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-0.rs index 2acfb06926..ba8980be00 100644 --- a/tests/expectations/tests/template-param-usage-0.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-0.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } impl Default for UsesTemplateParameter { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template-param-usage-1.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-1.rs new file mode 100644 index 0000000000..7cbec9610d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-1.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct DoesNotUseTemplateParameter { + pub x: ::std::os::raw::c_int, +} diff --git a/tests/expectations/tests/template-param-usage-10.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-10.rs similarity index 92% rename from tests/expectations/tests/template-param-usage-10.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-10.rs index c6034fb8fe..a4e5d0ce82 100644 --- a/tests/expectations/tests/template-param-usage-10.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-10.rs @@ -1,26 +1,20 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct DoublyIndirectUsage { - pub doubly_indirect: DoublyIndirectUsage_IndirectUsage, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub doubly_indirect: DoublyIndirectUsage_IndirectUsage, } pub type DoublyIndirectUsage_Aliased = T; pub type DoublyIndirectUsage_Typedefed = U; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct DoublyIndirectUsage_IndirectUsage { - pub member: DoublyIndirectUsage_Aliased, - pub another: DoublyIndirectUsage_Typedefed, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: DoublyIndirectUsage_Aliased, + pub another: DoublyIndirectUsage_Typedefed, } impl Default for DoublyIndirectUsage_IndirectUsage { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template-param-usage-11.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-11.rs new file mode 100644 index 0000000000..e914375875 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-11.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct DoesNotUseT { + pub _address: u8, +} diff --git a/tests/expectations/tests/template-param-usage-12.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-12.rs similarity index 89% rename from tests/expectations/tests/template-param-usage-12.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-12.rs index 626e451af4..7f3a306b6b 100644 --- a/tests/expectations/tests/template-param-usage-12.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-12.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct BaseUsesT { - pub t: *mut T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: *mut T, } impl Default for BaseUsesT { fn default() -> Self { @@ -23,9 +17,9 @@ impl Default for BaseUsesT { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct CrtpUsesU { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _base: BaseUsesT>, pub usage: U, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for CrtpUsesU { fn default() -> Self { diff --git a/tests/expectations/tests/template-param-usage-13.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-13.rs similarity index 84% rename from tests/expectations/tests/template-param-usage-13.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-13.rs index 70c1778bd5..185f16be11 100644 --- a/tests/expectations/tests/template-param-usage-13.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-13.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct BaseIgnoresT { @@ -13,9 +7,9 @@ pub struct BaseIgnoresT { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct CrtpUsesU { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _base: BaseIgnoresT, pub usage: U, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for CrtpUsesU { fn default() -> Self { diff --git a/tests/expectations/tests/template-param-usage-14.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-14.rs similarity index 82% rename from tests/expectations/tests/template-param-usage-14.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-14.rs index 0e0fd0c9ef..b008bb5b8f 100644 --- a/tests/expectations/tests/template-param-usage-14.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-14.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct BaseIgnoresT { diff --git a/tests/expectations/tests/template-param-usage-15.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-15.rs similarity index 88% rename from tests/expectations/tests/template-param-usage-15.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-15.rs index 941c607321..fced6dc58c 100644 --- a/tests/expectations/tests/template-param-usage-15.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-15.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct BaseUsesT { - pub usage: *mut T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub usage: *mut T, } impl Default for BaseUsesT { fn default() -> Self { diff --git a/tests/expectations/tests/template-param-usage-2.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-2.rs similarity index 89% rename from tests/expectations/tests/template-param-usage-2.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-2.rs index 0ad5d7bb69..4c671ce2ab 100644 --- a/tests/expectations/tests/template-param-usage-2.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-2.rs @@ -1,21 +1,15 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter_AlsoUsesTemplateParameter { - pub also: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub also: T, } impl Default for UsesTemplateParameter_AlsoUsesTemplateParameter { fn default() -> Self { diff --git a/tests/expectations/tests/template-param-usage-3.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-3.rs similarity index 83% rename from tests/expectations/tests/template-param-usage-3.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-3.rs index 414818d920..511365e656 100644 --- a/tests/expectations/tests/template-param-usage-3.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-3.rs @@ -1,27 +1,19 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter_AlsoUsesTemplateParameterAndMore { - pub also: T, - pub more: U, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub also: T, + pub more: U, } -impl Default - for UsesTemplateParameter_AlsoUsesTemplateParameterAndMore -{ +impl Default for UsesTemplateParameter_AlsoUsesTemplateParameterAndMore { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { diff --git a/tests/expectations/tests/template-param-usage-4.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-4.rs similarity index 85% rename from tests/expectations/tests/template-param-usage-4.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-4.rs index afcba978de..5655a6d260 100644 --- a/tests/expectations/tests/template-param-usage-4.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-4.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct UsesTemplateParameter { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] diff --git a/tests/expectations/tests/template-param-usage-5.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-5.rs similarity index 84% rename from tests/expectations/tests/template-param-usage-5.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-5.rs index 2cc8db6fe2..5049559b33 100644 --- a/tests/expectations/tests/template-param-usage-5.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-5.rs @@ -1,15 +1,9 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct IndirectlyUsesTemplateParameter { - pub aliased: IndirectlyUsesTemplateParameter_Aliased, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub aliased: IndirectlyUsesTemplateParameter_Aliased, } pub type IndirectlyUsesTemplateParameter_Aliased = T; impl Default for IndirectlyUsesTemplateParameter { diff --git a/bindgen-tests/tests/expectations/tests/template-param-usage-6.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-6.rs new file mode 100644 index 0000000000..0a08bc9da9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-6.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct DoesNotUseTemplateParameter { + pub x: ::std::os::raw::c_int, +} +pub type DoesNotUseTemplateParameter_ButAliasDoesUseIt = T; diff --git a/tests/expectations/tests/template-param-usage-7.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-7.rs similarity index 85% rename from tests/expectations/tests/template-param-usage-7.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-7.rs index 3ed7a45dfc..1552ae852f 100644 --- a/tests/expectations/tests/template-param-usage-7.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-7.rs @@ -1,17 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct DoesNotUseU { - pub t: T, - pub v: V, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, + pub v: V, } impl Default for DoesNotUseU { fn default() -> Self { diff --git a/tests/expectations/tests/template-param-usage-8.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-8.rs similarity index 86% rename from tests/expectations/tests/template-param-usage-8.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-8.rs index f8ac671410..61de18a833 100644 --- a/tests/expectations/tests/template-param-usage-8.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-8.rs @@ -1,17 +1,11 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct IndirectUsage { - pub member1: IndirectUsage_Typedefed, - pub member2: IndirectUsage_Aliased, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member1: IndirectUsage_Typedefed, + pub member2: IndirectUsage_Aliased, } pub type IndirectUsage_Typedefed = T; pub type IndirectUsage_Aliased = U; diff --git a/tests/expectations/tests/template-param-usage-9.rs b/bindgen-tests/tests/expectations/tests/template-param-usage-9.rs similarity index 88% rename from tests/expectations/tests/template-param-usage-9.rs rename to bindgen-tests/tests/expectations/tests/template-param-usage-9.rs index a50079a2ed..ff0eedc8ae 100644 --- a/tests/expectations/tests/template-param-usage-9.rs +++ b/bindgen-tests/tests/expectations/tests/template-param-usage-9.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct DoesNotUse { @@ -15,10 +9,10 @@ pub type DoesNotUse_Typedefed = U; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct DoesNotUse_IndirectUsage { - pub member: DoesNotUse_Aliased, - pub another: DoesNotUse_Typedefed, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: DoesNotUse_Aliased, + pub another: DoesNotUse_Typedefed, } impl Default for DoesNotUse_IndirectUsage { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template-with-var.rs b/bindgen-tests/tests/expectations/tests/template-with-var.rs new file mode 100644 index 0000000000..cdc0b5b149 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template-with-var.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TemplateWithVar { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/template.rs b/bindgen-tests/tests/expectations/tests/template.rs new file mode 100644 index 0000000000..94678cb49e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template.rs @@ -0,0 +1,566 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct Foo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_member: T, + pub m_member_ptr: *mut T, + pub m_member_arr: [T; 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() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct B { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_member: T, +} +impl Default for B { + 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}_Z3bar3FooIiiE"] + pub fn bar(foo: Foo<::std::os::raw::c_int>); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mozilla_Foo { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct C { + pub mB: B<::std::os::raw::c_uint>, + pub mBConstPtr: B<*const ::std::os::raw::c_int>, + pub mBConstStructPtr: B<*const mozilla_Foo>, + pub mBConstStructPtrArray: B<[*const mozilla_Foo; 1usize]>, + pub mBConst: B<::std::os::raw::c_int>, + pub mBVolatile: B<::std::os::raw::c_int>, + pub mBConstBool: B, + pub mBConstChar: B, + pub mBArray: B<[::std::os::raw::c_int; 1usize]>, + pub mBPtrArray: B<[*mut ::std::os::raw::c_int; 1usize]>, + pub mBArrayPtr: B<*mut [::std::os::raw::c_int; 1usize]>, + pub mBRef: B<*mut ::std::os::raw::c_int>, + pub mBConstRef: B<*const ::std::os::raw::c_int>, + pub mPtrRef: B<*mut *mut ::std::os::raw::c_int>, + pub mArrayRef: B<*mut [::std::os::raw::c_int; 1usize]>, + pub mBConstArray: B<[::std::os::raw::c_int; 1usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 104usize]; + ["Alignment of C"][::std::mem::align_of::() - 8usize]; + ["Offset of field: C::mB"][::std::mem::offset_of!(C, mB) - 0usize]; + ["Offset of field: C::mBConstPtr"][::std::mem::offset_of!(C, mBConstPtr) - 8usize]; + [ + "Offset of field: C::mBConstStructPtr", + ][::std::mem::offset_of!(C, mBConstStructPtr) - 16usize]; + [ + "Offset of field: C::mBConstStructPtrArray", + ][::std::mem::offset_of!(C, mBConstStructPtrArray) - 24usize]; + ["Offset of field: C::mBConst"][::std::mem::offset_of!(C, mBConst) - 32usize]; + ["Offset of field: C::mBVolatile"][::std::mem::offset_of!(C, mBVolatile) - 36usize]; + [ + "Offset of field: C::mBConstBool", + ][::std::mem::offset_of!(C, mBConstBool) - 40usize]; + [ + "Offset of field: C::mBConstChar", + ][::std::mem::offset_of!(C, mBConstChar) - 42usize]; + ["Offset of field: C::mBArray"][::std::mem::offset_of!(C, mBArray) - 44usize]; + ["Offset of field: C::mBPtrArray"][::std::mem::offset_of!(C, mBPtrArray) - 48usize]; + ["Offset of field: C::mBArrayPtr"][::std::mem::offset_of!(C, mBArrayPtr) - 56usize]; + ["Offset of field: C::mBRef"][::std::mem::offset_of!(C, mBRef) - 64usize]; + ["Offset of field: C::mBConstRef"][::std::mem::offset_of!(C, mBConstRef) - 72usize]; + ["Offset of field: C::mPtrRef"][::std::mem::offset_of!(C, mPtrRef) - 80usize]; + ["Offset of field: C::mArrayRef"][::std::mem::offset_of!(C, mArrayRef) - 88usize]; + [ + "Offset of field: C::mBConstArray", + ][::std::mem::offset_of!(C, mBConstArray) - 96usize]; +}; +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() + } + } +} +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct D { + pub m_foo: D_MyFoo, +} +pub type D_MyFoo = Foo<::std::os::raw::c_int>; +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct D_U { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_nested_foo: D_MyFoo, + pub m_baz: Z, +} +impl Default for D_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() + } + } +} +impl Default for D { + 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, Hash, PartialEq, Eq)] +pub struct Rooted { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub prev: *mut T, + pub next: *mut Rooted<*mut ::std::os::raw::c_void>, + pub ptr: T, +} +impl Default for Rooted { + 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, Hash, PartialEq, Eq)] +pub struct RootedContainer { + pub root: Rooted<*mut ::std::os::raw::c_void>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of RootedContainer"][::std::mem::size_of::() - 24usize]; + ["Alignment of RootedContainer"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: RootedContainer::root", + ][::std::mem::offset_of!(RootedContainer, root) - 0usize]; +}; +impl Default for RootedContainer { + 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 type WithDtorIntFwd = WithDtor<::std::os::raw::c_int>; +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct WithDtor { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, +} +impl Default for WithDtor { + 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, Hash, PartialEq, Eq)] +pub struct PODButContainsDtor { + pub member: WithDtorIntFwd, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PODButContainsDtor"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of PODButContainsDtor", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: PODButContainsDtor::member", + ][::std::mem::offset_of!(PODButContainsDtor, member) - 0usize]; +}; +impl Default for PODButContainsDtor { + 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, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Opaque { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct POD { + pub opaque_member: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of POD"][::std::mem::size_of::() - 4usize]; + ["Alignment of POD"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: POD::opaque_member", + ][::std::mem::offset_of!(POD, opaque_member) - 0usize]; +}; +///
+#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct NestedReplaced { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub buff: *mut T, +} +impl Default for NestedReplaced { + 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, Hash, PartialEq, Eq)] +pub struct NestedBase { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub buff: *mut T, +} +impl Default for NestedBase { + 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, Hash, PartialEq, Eq)] +pub struct NestedContainer { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub c: T, + pub nested: NestedReplaced, + pub inc: Incomplete, +} +impl Default for NestedContainer { + 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, Hash, PartialEq, Eq)] +pub struct Incomplete { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub d: T, +} +impl Default for Incomplete { + 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, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Untemplated { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Untemplated"][::std::mem::size_of::() - 1usize]; + ["Alignment of Untemplated"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Templated { + pub m_untemplated: Untemplated, +} +/** If the replacement doesn't happen at the parse level the container would be + copy and the replacement wouldn't, so this wouldn't compile. + +
*/ +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct ReplacedWithoutDestructor { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub buff: *mut T, +} +impl Default for ReplacedWithoutDestructor { + 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, Hash, PartialEq, Eq)] +pub struct ShouldNotBeCopiable { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_member: ReplacedWithoutDestructor, +} +impl Default for ShouldNotBeCopiable { + 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, Hash, PartialEq, Eq)] +pub struct ShouldNotBeCopiableAsWell { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub m_member: ReplacedWithoutDestructorFwd, +} +impl Default for ShouldNotBeCopiableAsWell { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +/** If the replacement doesn't happen at the parse level the container would be + copy and the replacement wouldn't, so this wouldn't compile. + +
*/ +#[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct ReplacedWithoutDestructorFwd { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub buff: *mut T, +} +impl Default for ReplacedWithoutDestructorFwd { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Foo_open0_int_int_close0", + ][::std::mem::size_of::>() - 24usize]; + [ + "Align of template specialization: Foo_open0_int_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_unsigned_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: B_open0_unsigned_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ptr_const_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ptr_const_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ptr_const_mozilla__Foo_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ptr_const_mozilla__Foo_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_array1_ptr_const_mozilla__Foo_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_array1_ptr_const_mozilla__Foo_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_const_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: B_open0_const_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_volatile_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: B_open0_volatile_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_const_bool_close0", + ][::std::mem::size_of::>() - 1usize]; + [ + "Align of template specialization: B_open0_const_bool_close0", + ][::std::mem::align_of::>() - 1usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_const_char16_t_close0", + ][::std::mem::size_of::>() - 2usize]; + [ + "Align of template specialization: B_open0_const_char16_t_close0", + ][::std::mem::align_of::>() - 2usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_array1_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: B_open0_array1_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_array1_ptr_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_array1_ptr_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ptr_array1_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ptr_array1_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ref_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ref_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ref_const_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ref_const_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ref_ptr_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ref_ptr_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_ref_array1_int_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: B_open0_ref_array1_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: B_open0_array1_const_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: B_open0_array1_const_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Foo_open0_int_int_close0", + ][::std::mem::size_of::>() - 24usize]; + [ + "Align of template specialization: Foo_open0_int_int_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Rooted_open0_ptr_void_close0", + ][::std::mem::size_of::>() - 24usize]; + [ + "Align of template specialization: Rooted_open0_ptr_void_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Rooted_open0_ptr_void_close0", + ][::std::mem::size_of::>() - 24usize]; + [ + "Align of template specialization: Rooted_open0_ptr_void_close0", + ][::std::mem::align_of::>() - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: WithDtor_open0_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: WithDtor_open0_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; diff --git a/tests/expectations/tests/template_alias.rs b/bindgen-tests/tests/expectations/tests/template_alias.rs similarity index 82% rename from tests/expectations/tests/template_alias.rs rename to bindgen-tests/tests/expectations/tests/template_alias.rs index 7e0af20d78..b270c9f3a4 100644 --- a/tests/expectations/tests/template_alias.rs +++ b/bindgen-tests/tests/expectations/tests/template_alias.rs @@ -1,16 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type JS_detail_Wrapped = T; #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct JS_Rooted { - pub ptr: JS_detail_Wrapped, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: JS_detail_Wrapped, } impl Default for JS_Rooted { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template_alias_basic.rs b/bindgen-tests/tests/expectations/tests/template_alias_basic.rs new file mode 100644 index 0000000000..d0f8f104c7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template_alias_basic.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type Wrapped = T; diff --git a/tests/expectations/tests/template_alias_namespace.rs b/bindgen-tests/tests/expectations/tests/template_alias_namespace.rs similarity index 81% rename from tests/expectations/tests/template_alias_namespace.rs rename to bindgen-tests/tests/expectations/tests/template_alias_namespace.rs index 7196b532f6..0aa5fc679a 100644 --- a/tests/expectations/tests/template_alias_namespace.rs +++ b/bindgen-tests/tests/expectations/tests/template_alias_namespace.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![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)] @@ -20,9 +14,8 @@ pub mod root { #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rooted { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub ptr: root::JS::detail::Wrapped, - pub _phantom_0: - ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for Rooted { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template_fun.rs b/bindgen-tests/tests/expectations/tests/template_fun.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template_fun.rs @@ -0,0 +1 @@ +#![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/template_instantiation_with_fn_local_type.rs b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs new file mode 100644 index 0000000000..085278e603 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs @@ -0,0 +1,58 @@ +#![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, +} +unsafe extern "C" { + #[link_name = "\u{1}_Z1fv"] + pub fn f(); +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Foo_open0_Bar_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: Foo_open0_Bar_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 1usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 1usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: Foo_open0_Boo_close0", + ][::std::mem::size_of::() - 1usize]; + [ + "Align of template specialization: Foo_open0_Boo_close0", + ][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Boo { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Boo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Boo"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/template_partial_specification.rs b/bindgen-tests/tests/expectations/tests/template_partial_specification.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template_partial_specification.rs @@ -0,0 +1 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] \ No newline at end of file diff --git a/tests/expectations/tests/template_typedef_transitive_param.rs b/bindgen-tests/tests/expectations/tests/template_typedef_transitive_param.rs similarity index 85% rename from tests/expectations/tests/template_typedef_transitive_param.rs rename to bindgen-tests/tests/expectations/tests/template_typedef_transitive_param.rs index 68ca126ac9..2efdde944e 100644 --- a/tests/expectations/tests/template_typedef_transitive_param.rs +++ b/bindgen-tests/tests/expectations/tests/template_typedef_transitive_param.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct Wrapper { @@ -13,8 +7,8 @@ pub struct Wrapper { #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Wrapper_Wrapped { - pub t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub t: T, } impl Default for Wrapper_Wrapped { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/template_typedefs.rs b/bindgen-tests/tests/expectations/tests/template_typedefs.rs new file mode 100644 index 0000000000..71f0732a63 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/template_typedefs.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type foo = ::std::option::Option; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +pub type Foo_Char = T; +pub type Foo_FooPtrTypedef = *mut Foo_Char; +pub type Foo_nsCOMArrayEnumFunc = ::std::option::Option< + unsafe extern "C" fn(aElement: *mut T, aData: *mut ::std::os::raw::c_void) -> bool, +>; diff --git a/tests/expectations/tests/templateref_opaque.rs b/bindgen-tests/tests/expectations/tests/templateref_opaque.rs similarity index 76% rename from tests/expectations/tests/templateref_opaque.rs rename to bindgen-tests/tests/expectations/tests/templateref_opaque.rs index 70cef86717..8f73e86c31 100644 --- a/tests/expectations/tests/templateref_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/templateref_opaque.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct detail_PointerType { diff --git a/bindgen-tests/tests/expectations/tests/templatized-bitfield.rs b/bindgen-tests/tests/expectations/tests/templatized-bitfield.rs new file mode 100644 index 0000000000..1b3e712361 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/templatized-bitfield.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +/** We don't get a layout for this bitfield, since we don't know what `T` will + be, so we cannot allocate bitfield units. The best thing we can do is make + the struct opaque.*/ +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct TemplatizedBitfield { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/test_macro_fallback_non_system_dir.rs b/bindgen-tests/tests/expectations/tests/test_macro_fallback_non_system_dir.rs new file mode 100644 index 0000000000..bf9739f3fa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/test_macro_fallback_non_system_dir.rs @@ -0,0 +1,6 @@ +pub const CONST: u32 = 5; +pub const OTHER_CONST: u32 = 6; +pub const LARGE_CONST: u32 = 1536; +pub const THE_CONST: u32 = 28; +pub const MY_CONST: u32 = 69; +pub const NEGATIVE: i32 = -1; 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 new file mode 100644 index 0000000000..e1872623bc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/test_mixed_header_and_header_contents.rs @@ -0,0 +1,50 @@ +unsafe extern "C" { + pub static mut foo: ::std::option::Option< + unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + >; +} +unsafe extern "C" { + pub fn bar(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn bar2(b: *const ::std::os::raw::c_char) -> f32; +} +pub type Char = ::std::os::raw::c_char; +pub type SChar = ::std::os::raw::c_schar; +pub type UChar = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Test { + pub ch: ::std::os::raw::c_char, + pub u: ::std::os::raw::c_uchar, + pub d: ::std::os::raw::c_schar, + pub cch: ::std::os::raw::c_char, + pub cu: ::std::os::raw::c_uchar, + pub cd: ::std::os::raw::c_schar, + pub Cch: Char, + pub Cu: UChar, + pub Cd: SChar, + pub Ccch: Char, + pub Ccu: UChar, + pub Ccd: SChar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 12usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Test::ch"][::std::mem::offset_of!(Test, ch) - 0usize]; + ["Offset of field: Test::u"][::std::mem::offset_of!(Test, u) - 1usize]; + ["Offset of field: Test::d"][::std::mem::offset_of!(Test, d) - 2usize]; + ["Offset of field: Test::cch"][::std::mem::offset_of!(Test, cch) - 3usize]; + ["Offset of field: Test::cu"][::std::mem::offset_of!(Test, cu) - 4usize]; + ["Offset of field: Test::cd"][::std::mem::offset_of!(Test, cd) - 5usize]; + ["Offset of field: Test::Cch"][::std::mem::offset_of!(Test, Cch) - 6usize]; + ["Offset of field: Test::Cu"][::std::mem::offset_of!(Test, Cu) - 7usize]; + ["Offset of field: Test::Cd"][::std::mem::offset_of!(Test, Cd) - 8usize]; + ["Offset of field: Test::Ccch"][::std::mem::offset_of!(Test, Ccch) - 9usize]; + ["Offset of field: Test::Ccu"][::std::mem::offset_of!(Test, Ccu) - 10usize]; + ["Offset of field: Test::Ccd"][::std::mem::offset_of!(Test, Ccd) - 11usize]; +}; 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 new file mode 100644 index 0000000000..2e62ac902f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/test_multiple_header_calls_in_builder.rs @@ -0,0 +1,44 @@ +unsafe extern "C" { + pub static mut foo: ::std::option::Option< + unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + >; +} +pub type Char = ::std::os::raw::c_char; +pub type SChar = ::std::os::raw::c_schar; +pub type UChar = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Test { + pub ch: ::std::os::raw::c_char, + pub u: ::std::os::raw::c_uchar, + pub d: ::std::os::raw::c_schar, + pub cch: ::std::os::raw::c_char, + pub cu: ::std::os::raw::c_uchar, + pub cd: ::std::os::raw::c_schar, + pub Cch: Char, + pub Cu: UChar, + pub Cd: SChar, + pub Ccch: Char, + pub Ccu: UChar, + pub Ccd: SChar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 12usize]; + ["Alignment of Test"][::std::mem::align_of::() - 1usize]; + ["Offset of field: Test::ch"][::std::mem::offset_of!(Test, ch) - 0usize]; + ["Offset of field: Test::u"][::std::mem::offset_of!(Test, u) - 1usize]; + ["Offset of field: Test::d"][::std::mem::offset_of!(Test, d) - 2usize]; + ["Offset of field: Test::cch"][::std::mem::offset_of!(Test, cch) - 3usize]; + ["Offset of field: Test::cu"][::std::mem::offset_of!(Test, cu) - 4usize]; + ["Offset of field: Test::cd"][::std::mem::offset_of!(Test, cd) - 5usize]; + ["Offset of field: Test::Cch"][::std::mem::offset_of!(Test, Cch) - 6usize]; + ["Offset of field: Test::Cu"][::std::mem::offset_of!(Test, Cu) - 7usize]; + ["Offset of field: Test::Cd"][::std::mem::offset_of!(Test, Cd) - 8usize]; + ["Offset of field: Test::Ccch"][::std::mem::offset_of!(Test, Ccch) - 9usize]; + ["Offset of field: Test::Ccu"][::std::mem::offset_of!(Test, Ccu) - 10usize]; + ["Offset of field: Test::Ccd"][::std::mem::offset_of!(Test, Ccd) - 11usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/timex.rs b/bindgen-tests/tests/expectations/tests/timex.rs new file mode 100644 index 0000000000..f73b608de2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/timex.rs @@ -0,0 +1,589 @@ +#![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 timex { + pub tai: ::std::os::raw::c_int, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of timex"][::std::mem::size_of::() - 48usize]; + ["Alignment of timex"][::std::mem::align_of::() - 4usize]; + ["Offset of field: timex::tai"][::std::mem::offset_of!(timex, tai) - 0usize]; +}; +impl Default for timex { + 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 timex_named { + pub tai: ::std::os::raw::c_int, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of timex_named"][::std::mem::size_of::() - 48usize]; + ["Alignment of timex_named"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: timex_named::tai", + ][::std::mem::offset_of!(timex_named, tai) - 0usize]; +}; +impl Default for timex_named { + 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 timex_named { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_int { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 32u8) as u32) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 32u8, val as u64) + } + } + #[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) } + } + #[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(32usize, 32u8, val as u64) + } + } + #[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) } + } + #[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(64usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_d(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(96usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_e(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(128usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_f(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(160usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_g(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(192usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_h(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(224usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_i(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(256usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_j(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(288usize, 32u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_k(&mut self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + 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 new file mode 100644 index 0000000000..7a12f2abb7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/transform-op.rs @@ -0,0 +1,251 @@ +#![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 const 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)] +pub struct StylePoint { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub x: T, + pub y: T, +} +impl Default for StylePoint { + 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)] +#[repr(align(1))] +pub struct StyleFoo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub __bindgen_anon_1: __BindgenUnionField, + pub foo: __BindgenUnionField>, + pub bar: __BindgenUnionField>, + pub baz: __BindgenUnionField>, + pub bindgen_union_field: [u8; 0usize], +} +pub const StyleFoo_Tag_Foo: StyleFoo_Tag = 0; +pub const StyleFoo_Tag_Bar: StyleFoo_Tag = 0; +pub const StyleFoo_Tag_Baz: StyleFoo_Tag = 0; +pub const StyleFoo_Tag_Bazz: StyleFoo_Tag = 0; +pub type StyleFoo_Tag = u8; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct StyleFoo_Foo_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub tag: StyleFoo_Tag, + pub x: i32, + pub y: StylePoint, + pub z: StylePoint, +} +impl Default for StyleFoo_Foo_Body { + 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 StyleFoo_Bar_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub tag: StyleFoo_Tag, + pub _0: T, +} +impl Default for StyleFoo_Bar_Body { + 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 StyleFoo_Baz_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub tag: StyleFoo_Tag, + pub _0: StylePoint, +} +impl Default for StyleFoo_Baz_Body { + 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 StyleFoo__bindgen_ty_1 { + pub tag: StyleFoo_Tag, +} +impl Default for StyleFoo__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 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)] +pub struct StyleBar { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub tag: StyleBar_Tag, + pub __bindgen_anon_1: StyleBar__bindgen_ty_1, +} +pub const StyleBar_Tag_Bar1: StyleBar_Tag = 0; +pub const StyleBar_Tag_Bar2: StyleBar_Tag = 0; +pub const StyleBar_Tag_Bar3: StyleBar_Tag = 0; +pub const StyleBar_Tag_Bar4: StyleBar_Tag = 0; +pub type StyleBar_Tag = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct StyleBar_StyleBar1_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub x: i32, + pub y: StylePoint, + pub z: StylePoint, +} +impl Default for StyleBar_StyleBar1_Body { + 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_StyleBar2_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _0: T, +} +impl Default for StyleBar_StyleBar2_Body { + 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_StyleBar3_Body { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub _0: StylePoint, +} +impl Default for StyleBar_StyleBar3_Body { + 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)] +#[repr(align(1))] +pub struct StyleBar__bindgen_ty_1 { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub bar1: __BindgenUnionField>, + pub bar2: __BindgenUnionField>, + 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 { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: StylePoint_open0_float_close0", + ][::std::mem::size_of::>() - 8usize]; + [ + "Align of template specialization: StylePoint_open0_float_close0", + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: StylePoint_open0_float_close0", + ][::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 new file mode 100644 index 0000000000..6d1c43d9cc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/type-referenced-by-allowlisted-function.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct dl_phdr_info { + pub x: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of dl_phdr_info"][::std::mem::size_of::() - 4usize]; + ["Alignment of dl_phdr_info"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: dl_phdr_info::x", + ][::std::mem::offset_of!(dl_phdr_info, x) - 0usize]; +}; +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/type_alias_empty.rs b/bindgen-tests/tests/expectations/tests/type_alias_empty.rs new file mode 100644 index 0000000000..2cbeb75570 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/type_alias_empty.rs @@ -0,0 +1,2 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type bool_constant = u8; diff --git a/tests/expectations/tests/type_alias_partial_template_especialization.rs b/bindgen-tests/tests/expectations/tests/type_alias_partial_template_especialization.rs similarity index 81% rename from tests/expectations/tests/type_alias_partial_template_especialization.rs rename to bindgen-tests/tests/expectations/tests/type_alias_partial_template_especialization.rs index 44449f20d1..29df017a9b 100644 --- a/tests/expectations/tests/type_alias_partial_template_especialization.rs +++ b/bindgen-tests/tests/expectations/tests/type_alias_partial_template_especialization.rs @@ -1,16 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type MaybeWrapped
= A; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Rooted { - pub ptr: MaybeWrapped, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub ptr: MaybeWrapped, } impl Default for Rooted { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/type_alias_template_specialized.rs b/bindgen-tests/tests/expectations/tests/type_alias_template_specialized.rs new file mode 100644 index 0000000000..13e3f8139c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/type_alias_template_specialized.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Rooted { + pub ptr: MaybeWrapped<::std::os::raw::c_int>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Rooted"][::std::mem::size_of::() - 4usize]; + ["Alignment of Rooted"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Rooted::ptr"][::std::mem::offset_of!(Rooted, ptr) - 0usize]; +}; +impl Default for Rooted { + 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 type MaybeWrapped
= a; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: MaybeWrapped_open0_int_close0", + ][::std::mem::size_of::>() - 4usize]; + [ + "Align of template specialization: MaybeWrapped_open0_int_close0", + ][::std::mem::align_of::>() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs b/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs new file mode 100644 index 0000000000..122059b4e1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs @@ -0,0 +1,87 @@ +#![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 inner: ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of foo"][::std::mem::align_of::() - 1usize]; + ["Offset of field: foo::inner"][::std::mem::offset_of!(foo, inner) - 0usize]; +}; +pub type foo_ptr = *const foo; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct bar { + pub inner: ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of bar"][::std::mem::align_of::() - 1usize]; + ["Offset of field: bar::inner"][::std::mem::offset_of!(bar, inner) - 0usize]; +}; +pub type bar_ptr = *mut bar; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct baz { + _unused: [u8; 0], +} +pub type baz_ptr = *mut baz; +#[repr(C)] +#[derive(Copy, Clone)] +pub union cat { + pub standard_issue: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of cat"][::std::mem::size_of::() - 4usize]; + ["Alignment of cat"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: cat::standard_issue", + ][::std::mem::offset_of!(cat, standard_issue) - 0usize]; +}; +impl Default for cat { + 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 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; +unsafe extern "C" { + pub fn takes_foo_ptr(arg1: foo_ptr); +} +unsafe extern "C" { + pub fn takes_foo_struct(arg1: foo); +} +unsafe extern "C" { + pub fn takes_bar_ptr(arg1: bar_ptr); +} +unsafe extern "C" { + pub fn takes_bar_struct(arg1: bar); +} +unsafe extern "C" { + pub fn takes_baz_ptr(arg1: baz_ptr); +} +unsafe extern "C" { + pub fn takes_baz_struct(arg1: baz); +} +unsafe extern "C" { + pub fn takes_cat_ptr(arg1: cat_ptr); +} +unsafe extern "C" { + pub fn takes_cat_union(arg1: cat); +} +unsafe extern "C" { + pub fn takes_mad_ptr(arg1: mad_ptr); +} +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 new file mode 100644 index 0000000000..994b327da7 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/typedefd-array-as-function-arg.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type myVector3 = [f32; 3usize]; +unsafe extern "C" { + pub fn modifyVectorFunc(v: *mut f32); +} diff --git a/bindgen-tests/tests/expectations/tests/typeref.rs b/bindgen-tests/tests/expectations/tests/typeref.rs new file mode 100644 index 0000000000..e48f0eb254 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/typeref.rs @@ -0,0 +1,105 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct mozilla_FragmentOrURL { + pub mIsLocalRef: bool, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of mozilla_FragmentOrURL", + ][::std::mem::size_of::() - 1usize]; + [ + "Alignment of mozilla_FragmentOrURL", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: mozilla_FragmentOrURL::mIsLocalRef", + ][::std::mem::offset_of!(mozilla_FragmentOrURL, mIsLocalRef) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct mozilla_Position { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of mozilla_Position"][::std::mem::size_of::() - 1usize]; + [ + "Alignment of mozilla_Position", + ][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +pub struct mozilla_StyleShapeSource { + pub __bindgen_anon_1: mozilla_StyleShapeSource__bindgen_ty_1, +} +#[repr(C)] +pub union mozilla_StyleShapeSource__bindgen_ty_1 { + pub mPosition: *mut mozilla_Position, + pub mFragmentOrURL: *mut mozilla_FragmentOrURL, +} +impl Default for mozilla_StyleShapeSource__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 mozilla_StyleShapeSource { + 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, Hash, PartialEq, Eq)] +pub struct Bar { + pub mFoo: *mut nsFoo, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 8usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Bar::mFoo"][::std::mem::offset_of!(Bar, mFoo) - 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() + } + } +} +#[repr(C)] +pub struct nsFoo { + pub mBar: mozilla_StyleShapeSource, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsFoo"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsFoo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: nsFoo::mBar"][::std::mem::offset_of!(nsFoo, mBar) - 0usize]; +}; +impl Default for nsFoo { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of template specialization: mozilla_StyleShapeSource_open0_int_close0", + ][::std::mem::size_of::() - 8usize]; + [ + "Align of template specialization: mozilla_StyleShapeSource_open0_int_close0", + ][::std::mem::align_of::() - 8usize]; +}; 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/underscore.rs b/bindgen-tests/tests/expectations/tests/underscore.rs new file mode 100644 index 0000000000..f94d5fc580 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/underscore.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const __: ::std::os::raw::c_int = 10; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ptr_t { + pub __: [::std::os::raw::c_uchar; 8usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ptr_t"][::std::mem::size_of::() - 8usize]; + ["Alignment of ptr_t"][::std::mem::align_of::() - 1usize]; + ["Offset of field: ptr_t::__"][::std::mem::offset_of!(ptr_t, __) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/union-align.rs b/bindgen-tests/tests/expectations/tests/union-align.rs new file mode 100644 index 0000000000..bdb1bb376e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union-align.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub union Bar { + pub foo: ::std::os::raw::c_uchar, +} +#[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 { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub union Baz { + pub bar: 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 { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/union-in-ns.rs b/bindgen-tests/tests/expectations/tests/union-in-ns.rs new file mode 100644 index 0000000000..781041addb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union-in-ns.rs @@ -0,0 +1,26 @@ +#![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(Copy, Clone)] + pub union bar { + pub baz: ::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::baz"][::std::mem::offset_of!(bar, baz) - 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/union_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_bitfield.rs new file mode 100644 index 0000000000..8df0724738 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -0,0 +1,340 @@ +#![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(Copy, Clone)] +pub union U4 { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of U4"][::std::mem::size_of::() - 4usize]; + ["Alignment of U4"][::std::mem::align_of::() - 4usize]; +}; +impl Default for U4 { + 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 U4 { + #[inline] + pub fn derp(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.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.set(0usize, 1u8, val as u64) + } + } + #[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]> { + 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(Copy, Clone)] +pub union B { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of B"][::std::mem::size_of::() - 4usize]; + ["Alignment of B"][::std::mem::align_of::() - 4usize]; +}; +impl Default for B { + 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 B { + #[inline] + pub fn foo(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.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.set(0usize, 31u8, val as u64) + } + } + #[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(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(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; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 31u8, + { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_dtor.rs b/bindgen-tests/tests/expectations/tests/union_dtor.rs new file mode 100644 index 0000000000..3b89587098 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_dtor.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub union UnionWithDtor { + pub mFoo: ::std::os::raw::c_int, + pub mBar: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of UnionWithDtor"][::std::mem::size_of::() - 8usize]; + ["Alignment of UnionWithDtor"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: UnionWithDtor::mFoo", + ][::std::mem::offset_of!(UnionWithDtor, mFoo) - 0usize]; + [ + "Offset of field: UnionWithDtor::mBar", + ][::std::mem::offset_of!(UnionWithDtor, mBar) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN13UnionWithDtorD1Ev"] + pub fn UnionWithDtor_UnionWithDtor_destructor(this: *mut UnionWithDtor); +} +impl Default for UnionWithDtor { + 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 UnionWithDtor { + #[inline] + pub unsafe fn destruct(&mut self) { + UnionWithDtor_UnionWithDtor_destructor(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_fields.rs b/bindgen-tests/tests/expectations/tests/union_fields.rs new file mode 100644 index 0000000000..c3d0f8db61 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_fields.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union nsStyleUnion { + pub mInt: ::std::os::raw::c_int, + pub mFloat: f32, + pub mPointer: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsStyleUnion"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsStyleUnion"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: nsStyleUnion::mInt", + ][::std::mem::offset_of!(nsStyleUnion, mInt) - 0usize]; + [ + "Offset of field: nsStyleUnion::mFloat", + ][::std::mem::offset_of!(nsStyleUnion, mFloat) - 0usize]; + [ + "Offset of field: nsStyleUnion::mPointer", + ][::std::mem::offset_of!(nsStyleUnion, mPointer) - 0usize]; +}; +impl Default for nsStyleUnion { + 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/tests/expectations/tests/union_template.rs b/bindgen-tests/tests/expectations/tests/union_template.rs similarity index 93% rename from tests/expectations/tests/union_template.rs rename to bindgen-tests/tests/expectations/tests/union_template.rs index 9c3d7a07eb..62019e6dd7 100644 --- a/tests/expectations/tests/union_template.rs +++ b/bindgen-tests/tests/expectations/tests/union_template.rs @@ -1,10 +1,4 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] pub struct NastyStruct { pub mIsSome: bool, diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct.rs new file mode 100644 index 0000000000..20f4dd2265 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} 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 new file mode 100644 index 0000000000..a1b61c035d --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -0,0 +1,281 @@ +#![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(Copy, Clone)] +pub union foo { + pub a: ::std::os::raw::c_int, + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo__bindgen_ty_1 { + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; +}; +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 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) } + } + #[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 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, + ) -> __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 + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::a"][::std::mem::offset_of!(foo, a) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_union.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_union.rs new file mode 100644 index 0000000000..212a159cd2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_union.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo { + pub bar: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub a: ::std::os::raw::c_uint, + pub b: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: foo__bindgen_ty_1::a", + ][::std::mem::offset_of!(foo__bindgen_ty_1, a) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct.rs new file mode 100644 index 0000000000..859188e891 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union pixel { + pub rgba: ::std::os::raw::c_uint, + pub __bindgen_anon_1: pixel__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, 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, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of pixel__bindgen_ty_1", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of pixel__bindgen_ty_1", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: pixel__bindgen_ty_1::r", + ][::std::mem::offset_of!(pixel__bindgen_ty_1, r) - 0usize]; + [ + "Offset of field: pixel__bindgen_ty_1::g", + ][::std::mem::offset_of!(pixel__bindgen_ty_1, g) - 1usize]; + [ + "Offset of field: pixel__bindgen_ty_1::b", + ][::std::mem::offset_of!(pixel__bindgen_ty_1, b) - 2usize]; + [ + "Offset of field: pixel__bindgen_ty_1::a", + ][::std::mem::offset_of!(pixel__bindgen_ty_1, a) - 3usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pixel"][::std::mem::size_of::() - 4usize]; + ["Alignment of pixel"][::std::mem::align_of::() - 4usize]; + ["Offset of field: pixel::rgba"][::std::mem::offset_of!(pixel, rgba) - 0usize]; +}; +impl Default for pixel { + 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/union_with_anon_unnamed_union.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_union.rs new file mode 100644 index 0000000000..6e136c0d92 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_union.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo { + pub a: ::std::os::raw::c_uint, + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1 { + pub b: ::std::os::raw::c_ushort, + pub c: ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 2usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: foo__bindgen_ty_1::b", + ][::std::mem::offset_of!(foo__bindgen_ty_1, b) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1::c", + ][::std::mem::offset_of!(foo__bindgen_ty_1, c) - 0usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::a"][::std::mem::offset_of!(foo, a) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_with_big_member.rs b/bindgen-tests/tests/expectations/tests/union_with_big_member.rs new file mode 100644 index 0000000000..9d69957a85 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_big_member.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union WithBigArray { + pub a: ::std::os::raw::c_int, + pub b: [::std::os::raw::c_int; 33usize], +} +#[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]; + [ + "Offset of field: WithBigArray::b", + ][::std::mem::offset_of!(WithBigArray, b) - 0usize]; +}; +impl Default for WithBigArray { + 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(Copy, Clone)] +pub union WithBigArray2 { + pub a: ::std::os::raw::c_int, + pub b: [::std::os::raw::c_char; 33usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithBigArray2"][::std::mem::size_of::() - 36usize]; + ["Alignment of WithBigArray2"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithBigArray2::a", + ][::std::mem::offset_of!(WithBigArray2, a) - 0usize]; + [ + "Offset of field: WithBigArray2::b", + ][::std::mem::offset_of!(WithBigArray2, b) - 0usize]; +}; +impl Default for WithBigArray2 { + 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(Copy, Clone)] +pub union WithBigMember { + pub a: ::std::os::raw::c_int, + pub b: WithBigArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithBigMember"][::std::mem::size_of::() - 132usize]; + ["Alignment of WithBigMember"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithBigMember::a", + ][::std::mem::offset_of!(WithBigMember, a) - 0usize]; + [ + "Offset of field: WithBigMember::b", + ][::std::mem::offset_of!(WithBigMember, b) - 0usize]; +}; +impl Default for WithBigMember { + 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/union_with_nesting.rs b/bindgen-tests/tests/expectations/tests/union_with_nesting.rs new file mode 100644 index 0000000000..5b60193ba4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_nesting.rs @@ -0,0 +1,104 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo { + pub a: ::std::os::raw::c_uint, + pub __bindgen_anon_1: foo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +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(Copy, Clone)] +pub union foo__bindgen_ty_1__bindgen_ty_1 { + pub b1: ::std::os::raw::c_ushort, + pub b2: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of foo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 2usize]; + [ + "Alignment of foo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::b1", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_1, b1) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::b2", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_1, b2) - 0usize]; +}; +impl Default for foo__bindgen_ty_1__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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union foo__bindgen_ty_1__bindgen_ty_2 { + pub c1: ::std::os::raw::c_ushort, + pub c2: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of foo__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::size_of::() - 2usize]; + [ + "Alignment of foo__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::c1", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, c1) - 0usize]; + [ + "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::c2", + ][::std::mem::offset_of!(foo__bindgen_ty_1__bindgen_ty_2, c2) - 0usize]; +}; +impl Default for foo__bindgen_ty_1__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo__bindgen_ty_1"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of foo__bindgen_ty_1", + ][::std::mem::align_of::() - 2usize]; +}; +impl Default for foo__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() + } + } +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 4usize]; + ["Alignment of foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: foo::a"][::std::mem::offset_of!(foo, a) - 0usize]; +}; +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() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/union_with_non_copy_member.rs b/bindgen-tests/tests/expectations/tests/union_with_non_copy_member.rs new file mode 100644 index 0000000000..d13c24d2d8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_non_copy_member.rs @@ -0,0 +1,142 @@ +#![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 const 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 NonCopyType { + pub foo: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NonCopyType"][::std::mem::size_of::() - 4usize]; + ["Alignment of NonCopyType"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: NonCopyType::foo", + ][::std::mem::offset_of!(NonCopyType, foo) - 0usize]; +}; +#[repr(C)] +pub struct WithBindgenGeneratedWrapper { + pub non_copy_type: __BindgenUnionField, + pub bar: __BindgenUnionField<::std::os::raw::c_int>, + pub bindgen_union_field: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of WithBindgenGeneratedWrapper", + ][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WithBindgenGeneratedWrapper", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithBindgenGeneratedWrapper::non_copy_type", + ][::std::mem::offset_of!(WithBindgenGeneratedWrapper, non_copy_type) - 0usize]; + [ + "Offset of field: WithBindgenGeneratedWrapper::bar", + ][::std::mem::offset_of!(WithBindgenGeneratedWrapper, bar) - 0usize]; +}; +impl Default for WithBindgenGeneratedWrapper { + 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 union WithManuallyDrop { + pub non_copy_type: ::std::mem::ManuallyDrop, + pub bar: ::std::mem::ManuallyDrop<::std::os::raw::c_int>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithManuallyDrop"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WithManuallyDrop", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithManuallyDrop::non_copy_type", + ][::std::mem::offset_of!(WithManuallyDrop, non_copy_type) - 0usize]; + [ + "Offset of field: WithManuallyDrop::bar", + ][::std::mem::offset_of!(WithManuallyDrop, bar) - 0usize]; +}; +impl Default for WithManuallyDrop { + 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 WithDefaultWrapper { + pub non_copy_type: __BindgenUnionField, + pub bar: __BindgenUnionField<::std::os::raw::c_int>, + pub bindgen_union_field: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithDefaultWrapper"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of WithDefaultWrapper", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: WithDefaultWrapper::non_copy_type", + ][::std::mem::offset_of!(WithDefaultWrapper, non_copy_type) - 0usize]; + [ + "Offset of field: WithDefaultWrapper::bar", + ][::std::mem::offset_of!(WithDefaultWrapper, bar) - 0usize]; +}; +impl Default for WithDefaultWrapper { + 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/union_with_zero_sized_array.rs b/bindgen-tests/tests/expectations/tests/union_with_zero_sized_array.rs new file mode 100644 index 0000000000..aa23fcd734 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/union_with_zero_sized_array.rs @@ -0,0 +1,68 @@ +#![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 const 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)] +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], +} +#[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 new file mode 100644 index 0000000000..d749dad977 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/unknown_attr.rs @@ -0,0 +1,28 @@ +#![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: __BindgenOpaqueArray8<[u8; 8usize]>, + pub __clang_max_align_nonce2: ::std::os::raw::c_longlong, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of max_align_t"][::std::mem::size_of::() - 32usize]; + ["Alignment of max_align_t"][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: max_align_t::__clang_max_align_nonce1", + ][::std::mem::offset_of!(max_align_t, __clang_max_align_nonce1) - 0usize]; + [ + "Offset of field: max_align_t::__clang_max_align_nonce2", + ][::std::mem::offset_of!(max_align_t, __clang_max_align_nonce2) - 16usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/unsorted-items.rs b/bindgen-tests/tests/expectations/tests/unsorted-items.rs new file mode 100644 index 0000000000..7d31c222a1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/unsorted-items.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn foo() -> ::std::os::raw::c_int; +} +pub type number = ::std::os::raw::c_int; +unsafe extern "C" { + pub fn bar(x: number) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Point { + pub x: number, + pub y: number, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Point"][::std::mem::size_of::() - 8usize]; + ["Alignment of Point"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Point::x"][::std::mem::offset_of!(Point, x) - 0usize]; + ["Offset of field: Point::y"][::std::mem::offset_of!(Point, y) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Angle { + pub a: number, + pub b: number, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Angle"][::std::mem::size_of::() - 8usize]; + ["Alignment of Angle"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Angle::a"][::std::mem::offset_of!(Angle, a) - 0usize]; + ["Offset of field: Angle::b"][::std::mem::offset_of!(Angle, b) - 4usize]; +}; +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 new file mode 100644 index 0000000000..8d495459a0 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/use-core.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(target_os = "windows"))] +extern crate core; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct foo { + pub a: ::core::ffi::c_int, + pub b: ::core::ffi::c_int, + pub bar: *mut ::core::ffi::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::core::mem::size_of::() - 16usize]; + ["Alignment of foo"][::core::mem::align_of::() - 8usize]; + ["Offset of field: foo::a"][::core::mem::offset_of!(foo, a) - 0usize]; + ["Offset of field: foo::b"][::core::mem::offset_of!(foo, b) - 4usize]; + ["Offset of field: foo::bar"][::core::mem::offset_of!(foo, bar) - 8usize]; +}; +impl Default for foo { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _bindgen_ty_1 { + pub bar: ::core::ffi::c_int, + pub baz: ::core::ffi::c_long, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _bindgen_ty_1"][::core::mem::size_of::<_bindgen_ty_1>() - 8usize]; + ["Alignment of _bindgen_ty_1"][::core::mem::align_of::<_bindgen_ty_1>() - 8usize]; + [ + "Offset of field: _bindgen_ty_1::bar", + ][::core::mem::offset_of!(_bindgen_ty_1, bar) - 0usize]; + [ + "Offset of field: _bindgen_ty_1::baz", + ][::core::mem::offset_of!(_bindgen_ty_1, baz) - 0usize]; +}; +impl Default for _bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +unsafe extern "C" { + pub static mut bazz: _bindgen_ty_1; +} +pub type fooFunction = ::core::option::Option< + unsafe extern "C" fn(bar: ::core::ffi::c_int), +>; diff --git a/tests/expectations/tests/using.rs b/bindgen-tests/tests/expectations/tests/using.rs similarity index 83% rename from tests/expectations/tests/using.rs rename to bindgen-tests/tests/expectations/tests/using.rs index 4749ed5552..9737fef0a5 100644 --- a/tests/expectations/tests/using.rs +++ b/bindgen-tests/tests/expectations/tests/using.rs @@ -1,16 +1,10 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Point { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub x: T, pub y: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for Point { fn default() -> Self { 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 new file mode 100644 index 0000000000..76ce0c50d6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/var-tracing.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub m_baz: ::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::m_baz"][::std::mem::offset_of!(Bar, m_baz) - 0usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3BarC1Ei"] + pub fn Bar_Bar(this: *mut Bar, baz: ::std::os::raw::c_int); +} +impl Bar { + #[inline] + pub unsafe fn new(baz: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + Bar_Bar(__bindgen_tmp.as_mut_ptr(), baz); + __bindgen_tmp.assume_init() + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN3Baz3FOOE"] + pub static Baz_FOO: [Bar; 0usize]; +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 1usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/variadic-method.rs b/bindgen-tests/tests/expectations/tests/variadic-method.rs new file mode 100644 index 0000000000..deac5f719e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/variadic-method.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "\u{1}_Z3fooPKcz"] + pub fn foo(fmt: *const ::std::os::raw::c_char, ...); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 1usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; +}; +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/variadic_template_function.rs b/bindgen-tests/tests/expectations/tests/variadic_template_function.rs new file mode 100644 index 0000000000..ee945f2599 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/variadic_template_function.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct VariadicFunctionObject { + pub _address: u8, +} diff --git a/bindgen-tests/tests/expectations/tests/vector.rs b/bindgen-tests/tests/expectations/tests/vector.rs new file mode 100644 index 0000000000..da53b4a8eb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/vector.rs @@ -0,0 +1,19 @@ +#![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 mMember: [::std::os::raw::c_longlong; 1usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 8usize]; + ["Alignment of foo"][::std::mem::align_of::() - 8usize]; + ["Offset of field: foo::mMember"][::std::mem::offset_of!(foo, mMember) - 0usize]; +}; +pub type __m128 = [f32; 4usize]; +pub type __m128d = [f64; 2usize]; +pub type __m128i = [::std::os::raw::c_longlong; 2usize]; +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 new file mode 100644 index 0000000000..d42be25202 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/virtual_dtor.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct nsSlots__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Debug)] +pub struct nsSlots { + pub vtable_: *const nsSlots__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsSlots"][::std::mem::size_of::() - 8usize]; + ["Alignment of nsSlots"][::std::mem::align_of::() - 8usize]; +}; +impl Default for nsSlots { + 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}_ZN7nsSlotsD1Ev"] + pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots); +} diff --git a/bindgen-tests/tests/expectations/tests/virtual_inheritance.rs b/bindgen-tests/tests/expectations/tests/virtual_inheritance.rs new file mode 100644 index 0000000000..6b5a855fae --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/virtual_inheritance.rs @@ -0,0 +1,56 @@ +#![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 foo: ::std::os::raw::c_int, +} +#[repr(C)] +pub struct B__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct B { + pub vtable_: *const B__bindgen_vtable, + pub bar: ::std::os::raw::c_int, +} +impl Default for B { + 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 C__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct C { + pub vtable_: *const C__bindgen_vtable, + pub baz: ::std::os::raw::c_int, +} +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() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct D { + pub _base: C, + pub _base_1: B, + pub bazz: ::std::os::raw::c_int, +} +impl Default for D { + 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/virtual_interface.rs b/bindgen-tests/tests/expectations/tests/virtual_interface.rs new file mode 100644 index 0000000000..44b245c4ea --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/virtual_interface.rs @@ -0,0 +1,94 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct PureVirtualIFace__bindgen_vtable { + pub PureVirtualIFace_Foo: unsafe extern "C" fn(this: *mut PureVirtualIFace), + pub PureVirtualIFace_Bar: unsafe extern "C" fn( + this: *mut PureVirtualIFace, + arg1: ::std::os::raw::c_uint, + ), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct PureVirtualIFace { + pub vtable_: *const PureVirtualIFace__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PureVirtualIFace"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of PureVirtualIFace", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for PureVirtualIFace { + 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 AnotherInterface__bindgen_vtable { + pub AnotherInterface_Baz: unsafe extern "C" fn(this: *mut AnotherInterface), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct AnotherInterface { + pub vtable_: *const AnotherInterface__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AnotherInterface"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of AnotherInterface", + ][::std::mem::align_of::() - 8usize]; +}; +impl Default for AnotherInterface { + 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 Implementation { + pub _base: PureVirtualIFace, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Implementation"][::std::mem::size_of::() - 8usize]; + ["Alignment of Implementation"][::std::mem::align_of::() - 8usize]; +}; +impl Default for Implementation { + 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 DoubleImpl { + pub _base: PureVirtualIFace, + pub _base_1: AnotherInterface, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of DoubleImpl"][::std::mem::size_of::() - 16usize]; + ["Alignment of DoubleImpl"][::std::mem::align_of::() - 8usize]; +}; +impl Default for DoubleImpl { + 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/virtual_overloaded.rs b/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs new file mode 100644 index 0000000000..4c3702faeb --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct C__bindgen_vtable { + pub C_do_thing: unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_char), + pub C_do_thing1: unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_int), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct C { + pub vtable_: *const C__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 8usize]; + ["Alignment of C"][::std::mem::align_of::() - 8usize]; +}; +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() + } + } +} +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); +} +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 new file mode 100644 index 0000000000..4997d49086 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/void_typedef.rs @@ -0,0 +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; +unsafe extern "C" { + pub fn this_api_returns_nothing(); +} +unsafe extern "C" { + pub fn this_api_also_returns_nothing(); +} +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 new file mode 100644 index 0000000000..9b9c2467aa --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/vtable_recursive_sig.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct Base__bindgen_vtable { + pub Base_AsDerived: unsafe extern "C" fn(this: *mut Base) -> *mut Derived, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Base { + pub vtable_: *const Base__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Base"][::std::mem::size_of::() - 8usize]; + ["Alignment of Base"][::std::mem::align_of::() - 8usize]; +}; +impl Default for Base { + 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}_ZN4Base9AsDerivedEv"] + pub fn Base_AsDerived(this: *mut ::std::os::raw::c_void) -> *mut Derived; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Derived { + pub _base: Base, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Derived"][::std::mem::size_of::() - 8usize]; + ["Alignment of Derived"][::std::mem::align_of::() - 8usize]; +}; +impl Default for Derived { + 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/wasm-constructor-returns.rs b/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs new file mode 100644 index 0000000000..ee26600a6b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs @@ -0,0 +1,26 @@ +#![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]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN3FooC1Ei"] + pub fn Foo_Foo( + this: *mut Foo, + var: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; +} +impl Foo { + #[inline] + pub unsafe fn new(var: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + Foo_Foo(__bindgen_tmp.as_mut_ptr(), var); + __bindgen_tmp.assume_init() + } +} diff --git a/bindgen-tests/tests/expectations/tests/wasm-import-module.rs b/bindgen-tests/tests/expectations/tests/wasm-import-module.rs new file mode 100644 index 0000000000..aeeb17f1c1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wasm-import-module.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[link(wasm_import_module = "test-module")] +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 new file mode 100644 index 0000000000..ca8d84520b --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs @@ -0,0 +1,574 @@ +#![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(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum nsStyleSVGOpacitySource { + eStyleSVGOpacitySource_Normal = 0, + eStyleSVGOpacitySource_ContextFillOpacity = 1, + eStyleSVGOpacitySource_ContextStrokeOpacity = 2, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Weird { + pub mStrokeDasharrayLength: ::std::os::raw::c_uint, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub mClipRule: ::std::os::raw::c_uchar, + pub mColorInterpolation: ::std::os::raw::c_uchar, + pub mColorInterpolationFilters: ::std::os::raw::c_uchar, + pub mFillRule: ::std::os::raw::c_uchar, + pub mImageRendering: ::std::os::raw::c_uchar, + pub mPaintOrder: ::std::os::raw::c_uchar, + pub mShapeRendering: ::std::os::raw::c_uchar, + pub mStrokeLinecap: ::std::os::raw::c_uchar, + pub mStrokeLinejoin: ::std::os::raw::c_uchar, + pub mTextAnchor: ::std::os::raw::c_uchar, + pub mTextRendering: ::std::os::raw::c_uchar, + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Weird"][::std::mem::size_of::() - 24usize]; + ["Alignment of Weird"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: Weird::mStrokeDasharrayLength", + ][::std::mem::offset_of!(Weird, mStrokeDasharrayLength) - 0usize]; + [ + "Offset of field: Weird::mClipRule", + ][::std::mem::offset_of!(Weird, mClipRule) - 8usize]; + [ + "Offset of field: Weird::mColorInterpolation", + ][::std::mem::offset_of!(Weird, mColorInterpolation) - 9usize]; + [ + "Offset of field: Weird::mColorInterpolationFilters", + ][::std::mem::offset_of!(Weird, mColorInterpolationFilters) - 10usize]; + [ + "Offset of field: Weird::mFillRule", + ][::std::mem::offset_of!(Weird, mFillRule) - 11usize]; + [ + "Offset of field: Weird::mImageRendering", + ][::std::mem::offset_of!(Weird, mImageRendering) - 12usize]; + [ + "Offset of field: Weird::mPaintOrder", + ][::std::mem::offset_of!(Weird, mPaintOrder) - 13usize]; + [ + "Offset of field: Weird::mShapeRendering", + ][::std::mem::offset_of!(Weird, mShapeRendering) - 14usize]; + [ + "Offset of field: Weird::mStrokeLinecap", + ][::std::mem::offset_of!(Weird, mStrokeLinecap) - 15usize]; + [ + "Offset of field: Weird::mStrokeLinejoin", + ][::std::mem::offset_of!(Weird, mStrokeLinejoin) - 16usize]; + [ + "Offset of field: Weird::mTextAnchor", + ][::std::mem::offset_of!(Weird, mTextAnchor) - 17usize]; + [ + "Offset of field: Weird::mTextRendering", + ][::std::mem::offset_of!(Weird, mTextRendering) - 18usize]; +}; +impl Default for Weird { + 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 Weird { + #[inline] + pub fn bitTest(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) } + } + #[inline] + pub fn set_bitTest(&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 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) } + } + #[inline] + pub fn set_bitTest2(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 15u8, val as u64) + } + } + #[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, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 16u8, + { + let bitTest: u32 = unsafe { ::std::mem::transmute(bitTest) }; + bitTest as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 15u8, + { + let bitTest2: u32 = unsafe { ::std::mem::transmute(bitTest2) }; + bitTest2 as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub fn mFillOpacitySource(&self) -> nsStyleSVGOpacitySource { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 3u8) as u32) } + } + #[inline] + pub fn set_mFillOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_mStrokeOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(3usize, 3u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_mStrokeDasharrayFromObject(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(6usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_mStrokeDashoffsetFromObject(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(7usize, 1u8, val as u64) + } + } + #[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) } + } + #[inline] + pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(8usize, 1u8, val as u64) + } + } + #[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, + mStrokeDasharrayFromObject: bool, + mStrokeDashoffsetFromObject: bool, + mStrokeWidthFromObject: bool, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 3u8, + { + let mFillOpacitySource: u32 = unsafe { + ::std::mem::transmute(mFillOpacitySource) + }; + mFillOpacitySource as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 3usize, + 3u8, + { + let mStrokeOpacitySource: u32 = unsafe { + ::std::mem::transmute(mStrokeOpacitySource) + }; + mStrokeOpacitySource as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 6usize, + 1u8, + { + let mStrokeDasharrayFromObject: u8 = unsafe { + ::std::mem::transmute(mStrokeDasharrayFromObject) + }; + mStrokeDasharrayFromObject as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 7usize, + 1u8, + { + let mStrokeDashoffsetFromObject: u8 = unsafe { + ::std::mem::transmute(mStrokeDashoffsetFromObject) + }; + mStrokeDashoffsetFromObject as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 1u8, + { + let mStrokeWidthFromObject: u8 = unsafe { + ::std::mem::transmute(mStrokeWidthFromObject) + }; + mStrokeWidthFromObject as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/what_is_going_on.rs b/bindgen-tests/tests/expectations/tests/what_is_going_on.rs new file mode 100644 index 0000000000..aaeab668e1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/what_is_going_on.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct UnknownUnits { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of UnknownUnits"][::std::mem::size_of::() - 1usize]; + ["Alignment of UnknownUnits"][::std::mem::align_of::() - 1usize]; +}; +pub type Float = f32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct PointTyped { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub x: F, + pub y: F, +} +impl Default for PointTyped { + 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 type IntPoint = PointTyped; diff --git a/bindgen-tests/tests/expectations/tests/win32-dtors.rs b/bindgen-tests/tests/expectations/tests/win32-dtors.rs new file mode 100644 index 0000000000..d7ed1290f8 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-dtors.rs @@ -0,0 +1,145 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct CppObj { + pub x: ::std::os::raw::c_int, +} +#[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); +} +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::MaybeUninit::uninit(); + CppObj_CppObj(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } + #[inline] + pub unsafe fn destruct(&mut self) { + CppObj_CppObj_destructor(self) + } +} +#[repr(C)] +pub struct CppObj2__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Debug)] +pub struct CppObj2 { + pub vtable_: *const CppObj2__bindgen_vtable, + pub x: ::std::os::raw::c_int, +} +#[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 { + ::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::MaybeUninit::uninit(); + CppObj2_CppObj2(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } +} +unsafe extern "C" { + #[link_name = "\u{1}??1CppObj2@@UEAA@XZ"] + pub fn CppObj2_CppObj2_destructor(this: *mut CppObj2); +} +#[repr(C)] +#[derive(Debug)] +pub struct CppObj3 { + pub _base: CppObj2, + pub x: ::std::os::raw::c_int, +} +#[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 { + ::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::MaybeUninit::uninit(); + CppObj3_CppObj3(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } +} +unsafe extern "C" { + #[link_name = "\u{1}??1CppObj3@@UEAA@XZ"] + pub fn CppObj3_CppObj3_destructor(this: *mut CppObj3); +} +#[repr(C)] +#[derive(Debug)] +pub struct CppObj4 { + pub _base: CppObj2, + pub x: ::std::os::raw::c_int, +} +#[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 { + ::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::MaybeUninit::uninit(); + CppObj4_CppObj4(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() + } +} +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_73.rs b/bindgen-tests/tests/expectations/tests/win32-thiscall_1_73.rs new file mode 100644 index 0000000000..4741f029ff --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-thiscall_1_73.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target = "i686-pc-windows-msvc")] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +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 "thiscall" { + #[link_name = "\u{1}?test@Foo@@QAEXXZ"] + pub fn Foo_test(this: *mut Foo); +} +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_nightly.rs b/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs new file mode 100644 index 0000000000..87b63574a9 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#![feature(abi_thiscall)] +#[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-vectorcall-nightly.rs b/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs new file mode 100644 index 0000000000..1c7b2fdbf6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(feature = "nightly")] +#![feature(abi_vectorcall)] +unsafe extern "vectorcall" { + #[link_name = "\u{1}test_vectorcall@@16"] + pub fn test_vectorcall( + a: ::std::os::raw::c_int, + b: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/win32-vectorcall.rs b/bindgen-tests/tests/expectations/tests/win32-vectorcall.rs new file mode 100644 index 0000000000..fe64295a68 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-vectorcall.rs @@ -0,0 +1 @@ +#![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/with_array_pointers_arguments.rs b/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs new file mode 100644 index 0000000000..7cc1d65daf --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn test_fn( + a: f32, + arr: *mut [::std::os::raw::c_int; 20usize], + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn test_fn2( + arr: *const [f32; 20usize], + 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" { + 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 new file mode 100644 index 0000000000..d642e84d27 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/without_array_pointers_arguments.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn test_fn(a: f32, arr: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +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), +>; +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 new file mode 100644 index 0000000000..bafcad8a7e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs @@ -0,0 +1,91 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + #[link_name = "foo__extern"] + pub fn foo() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "bar__extern"] + pub fn bar() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "takes_ptr__extern"] + pub fn takes_ptr(arg: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "takes_fn_ptr__extern"] + pub fn takes_fn_ptr( + f: ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "takes_fn__extern"] + pub fn takes_fn( + f: ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +pub type func = ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int, +>; +unsafe extern "C" { + #[link_name = "takes_alias__extern"] + pub fn takes_alias(f: func) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[link_name = "takes_qualified__extern"] + pub fn takes_qualified( + arg: *const *const ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +pub const foo_BAR: foo = 0; +pub type foo = ::std::os::raw::c_uint; +unsafe extern "C" { + #[link_name = "takes_enum__extern"] + pub fn takes_enum(f: foo) -> foo; +} +unsafe extern "C" { + #[link_name = "nevermore__extern"] + pub fn nevermore(); +} +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; +} +unsafe extern "C" { + #[link_name = "no_extra_argument__extern"] + pub fn no_extra_argument(va: *mut __va_list_tag); +} +unsafe extern "C" { + #[link_name = "many_va_list__extern"] + pub fn many_va_list( + i: ::std::os::raw::c_int, + va1: *mut __va_list_tag, + va2: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +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; +} +unsafe extern "C" { + #[link_name = "wrap_as_variadic_fn2__extern"] + pub fn wrap_as_variadic_fn2_wrapped(i: ::std::os::raw::c_int, ...); +} +pub type __builtin_va_list = [__va_list_tag; 1usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __va_list_tag { + pub gp_offset: ::std::os::raw::c_uint, + pub fp_offset: ::std::os::raw::c_uint, + pub overflow_arg_area: *mut ::std::os::raw::c_void, + pub reg_save_area: *mut ::std::os::raw::c_void, + _unused: [u8; 0], +} 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_class.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs new file mode 100644 index 0000000000..617a037631 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs @@ -0,0 +1,209 @@ +#![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 const 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] { + unsafe { ::std::slice::from_raw_parts(self.as_ptr(), len) } + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + unsafe { ::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)] +#[derive(Debug, Copy, Clone)] +pub struct C { + pub a: ::std::os::raw::c_int, + pub big_array: [::std::os::raw::c_char; 33usize], +} +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() + } + } +} +#[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>, +} +impl Default for C_with_zero_length_array { + 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, 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>, +} +#[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>, +} +impl Default for C_with_incomplete_array { + 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, Default)] +pub struct C_with_incomplete_array_2 { + pub a: ::std::os::raw::c_int, + pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, +} +#[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>, +} +impl Default for C_with_zero_length_array_and_incomplete_array { + 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, 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>, +} +#[repr(C)] +#[derive(Debug, Default)] +pub struct WithDtor { + pub b: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug)] +pub struct IncompleteArrayNonCopiable { + pub whatever: *mut ::std::os::raw::c_void, + pub incomplete_array: __IncompleteArrayField, +} +impl Default for IncompleteArrayNonCopiable { + 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(Copy, Clone)] +pub union Union { + pub d: f32, + pub i: ::std::os::raw::c_int, +} +impl Default for 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() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct WithUnion { + pub data: Union, +} +impl Default for WithUnion { + 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, Default, Copy, Clone)] +pub struct RealAbstractionWithTonsOfMethods { + pub _address: u8, +} +unsafe extern "C" { + #[link_name = "\u{1}_ZNK32RealAbstractionWithTonsOfMethods3barEv"] + pub fn RealAbstractionWithTonsOfMethods_bar( + this: *const RealAbstractionWithTonsOfMethods, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEv"] + pub fn RealAbstractionWithTonsOfMethods_bar1( + this: *mut RealAbstractionWithTonsOfMethods, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEi"] + pub fn RealAbstractionWithTonsOfMethods_bar2( + this: *mut RealAbstractionWithTonsOfMethods, + foo: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3staEv"] + pub fn RealAbstractionWithTonsOfMethods_sta(); +} +impl RealAbstractionWithTonsOfMethods { + #[inline] + pub unsafe fn bar(&self) { + unsafe { RealAbstractionWithTonsOfMethods_bar(self) } + } + #[inline] + pub unsafe fn bar1(&mut self) { + unsafe { RealAbstractionWithTonsOfMethods_bar1(self) } + } + #[inline] + pub unsafe fn bar2(&mut self, foo: ::std::os::raw::c_int) { + unsafe { RealAbstractionWithTonsOfMethods_bar2(self, foo) } + } + #[inline] + pub unsafe fn sta() { + unsafe { 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 new file mode 100644 index 0000000000..05be5d9944 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub struct TestLib { + __library: ::libloading::Library, + pub foo: Result< + unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub bar: Result< + unsafe extern "C" fn(x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + ::libloading::Error, + >, + pub baz: Result< + 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

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = unsafe { ::libloading::Library::new(path) }?; + unsafe { Self::from_library(library) } + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + 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( + &self, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int { + unsafe { (self.foo.as_ref().expect("Expected function, got error."))(x, y) } + } + pub unsafe fn bar(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { + unsafe { (self.bar.as_ref().expect("Expected function, got error."))(x) } + } + 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 new file mode 100644 index 0000000000..34252b10d3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_objc_class.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(target_os = "macos")] +use objc::{self, msg_send, sel, sel_impl, class}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +unsafe extern "C" { + pub static mut fooVar: Foo; +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct Foo(pub id); +impl std::ops::Deref for Foo { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for Foo {} +impl Foo { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(Foo), alloc) }) + } +} +impl IFoo for Foo {} +pub trait IFoo: Sized + std::ops::Deref { + unsafe fn method(&self) + where + ::Target: objc::Message + Sized, + { + unsafe { msg_send!(* self, method) } + } +} diff --git a/bindgen-tests/tests/expectations/tests/zero-size-array-align.rs b/bindgen-tests/tests/expectations/tests/zero-size-array-align.rs new file mode 100644 index 0000000000..48fc0cb1d6 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/zero-size-array-align.rs @@ -0,0 +1,50 @@ +#![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 const 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)] +#[derive(Debug, Default)] +pub struct dm_deps { + pub count: ::std::os::raw::c_uint, + pub filler: ::std::os::raw::c_uint, + pub device: __IncompleteArrayField<::std::os::raw::c_ulonglong>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of dm_deps"][::std::mem::size_of::() - 8usize]; + ["Alignment of dm_deps"][::std::mem::align_of::() - 8usize]; + ["Offset of field: dm_deps::count"][::std::mem::offset_of!(dm_deps, count) - 0usize]; + [ + "Offset of field: dm_deps::filler", + ][::std::mem::offset_of!(dm_deps, filler) - 4usize]; + [ + "Offset of field: dm_deps::device", + ][::std::mem::offset_of!(dm_deps, device) - 8usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/zero-sized-array.rs b/bindgen-tests/tests/expectations/tests/zero-sized-array.rs new file mode 100644 index 0000000000..229a6ee4db --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/zero-sized-array.rs @@ -0,0 +1,115 @@ +#![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 const 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") + } +} +/// Bizarrely enough, this should *not* get an `_address` field. +#[repr(C)] +#[derive(Debug, Default)] +pub struct ZeroSizedArray { + pub arr: __IncompleteArrayField<::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ZeroSizedArray"][::std::mem::size_of::() - 0usize]; + ["Alignment of ZeroSizedArray"][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ZeroSizedArray::arr", + ][::std::mem::offset_of!(ZeroSizedArray, arr) - 0usize]; +}; +/// And nor should this get an `_address` field. +#[repr(C)] +#[derive(Debug, Default)] +pub struct ContainsZeroSizedArray { + pub zsa: ZeroSizedArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsZeroSizedArray", + ][::std::mem::size_of::() - 0usize]; + [ + "Alignment of ContainsZeroSizedArray", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ContainsZeroSizedArray::zsa", + ][::std::mem::offset_of!(ContainsZeroSizedArray, zsa) - 0usize]; +}; +/** Inheriting from ZeroSizedArray shouldn't cause an `_address` to be inserted + either.*/ +#[repr(C)] +#[derive(Debug, Default)] +pub struct InheritsZeroSizedArray { + pub _base: ZeroSizedArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of InheritsZeroSizedArray", + ][::std::mem::size_of::() - 0usize]; + [ + "Alignment of InheritsZeroSizedArray", + ][::std::mem::align_of::() - 1usize]; +}; +/// And this should not get an `_address` field either. +#[repr(C)] +#[derive(Debug, Default)] +pub struct DynamicallySizedArray { + pub arr: __IncompleteArrayField<::std::os::raw::c_char>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of DynamicallySizedArray", + ][::std::mem::size_of::() - 0usize]; + [ + "Alignment of DynamicallySizedArray", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: DynamicallySizedArray::arr", + ][::std::mem::offset_of!(DynamicallySizedArray, arr) - 0usize]; +}; +/// No `_address` field here either. +#[repr(C)] +#[derive(Debug, Default)] +pub struct ContainsDynamicallySizedArray { + pub dsa: DynamicallySizedArray, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ContainsDynamicallySizedArray", + ][::std::mem::size_of::() - 0usize]; + [ + "Alignment of ContainsDynamicallySizedArray", + ][::std::mem::align_of::() - 1usize]; + [ + "Offset of field: ContainsDynamicallySizedArray::dsa", + ][::std::mem::offset_of!(ContainsDynamicallySizedArray, dsa) - 0usize]; +}; diff --git a/tests/headers/16-byte-alignment.h b/bindgen-tests/tests/headers/16-byte-alignment.h similarity index 100% rename from tests/headers/16-byte-alignment.h rename to bindgen-tests/tests/headers/16-byte-alignment.h diff --git a/tests/headers/381-decltype-alias.hpp b/bindgen-tests/tests/headers/381-decltype-alias.hpp similarity index 100% rename from tests/headers/381-decltype-alias.hpp rename to bindgen-tests/tests/headers/381-decltype-alias.hpp diff --git a/bindgen-tests/tests/headers/abi-override.h b/bindgen-tests/tests/headers/abi-override.h new file mode 100644 index 0000000000..0b0fdcf245 --- /dev/null +++ b/bindgen-tests/tests/headers/abi-override.h @@ -0,0 +1,9 @@ +// 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(); +void baz(); +void qux(); + +typedef void (*boo)(); +typedef void (*foobar)(boo boo); diff --git a/tests/headers/abi_variadic_function.hpp b/bindgen-tests/tests/headers/abi_variadic_function.hpp similarity index 100% rename from tests/headers/abi_variadic_function.hpp rename to bindgen-tests/tests/headers/abi_variadic_function.hpp diff --git a/tests/headers/accessors.hpp b/bindgen-tests/tests/headers/accessors.hpp similarity index 100% rename from tests/headers/accessors.hpp rename to bindgen-tests/tests/headers/accessors.hpp diff --git a/bindgen-tests/tests/headers/alias_comments.h b/bindgen-tests/tests/headers/alias_comments.h new file mode 100644 index 0000000000..2547c3c1a2 --- /dev/null +++ b/bindgen-tests/tests/headers/alias_comments.h @@ -0,0 +1,26 @@ +// bindgen-flags: --no-layout-tests + +/** + * This is Struct + */ +typedef struct { + /** + * This is field + */ + int field; +} Struct; + +/** + * This is AliasToStruct + */ +typedef Struct AliasToStruct; + +/** + * This is AliasToInt + */ +typedef int AliasToInt; + +/** + * This is AliasToAliasToInt + */ +typedef AliasToInt AliasToAliasToInt; diff --git a/tests/headers/allowlist-file.hpp b/bindgen-tests/tests/headers/allowlist-file.hpp similarity index 100% rename from tests/headers/allowlist-file.hpp rename to bindgen-tests/tests/headers/allowlist-file.hpp diff --git a/tests/headers/allowlist-namespaces-basic.hpp b/bindgen-tests/tests/headers/allowlist-namespaces-basic.hpp similarity index 100% rename from tests/headers/allowlist-namespaces-basic.hpp rename to bindgen-tests/tests/headers/allowlist-namespaces-basic.hpp diff --git a/tests/headers/allowlist-namespaces.hpp b/bindgen-tests/tests/headers/allowlist-namespaces.hpp similarity index 100% rename from tests/headers/allowlist-namespaces.hpp rename to bindgen-tests/tests/headers/allowlist-namespaces.hpp diff --git a/tests/headers/allowlist_basic.hpp b/bindgen-tests/tests/headers/allowlist_basic.hpp similarity index 100% rename from tests/headers/allowlist_basic.hpp rename to bindgen-tests/tests/headers/allowlist_basic.hpp diff --git a/tests/headers/allowlist_fix.hpp b/bindgen-tests/tests/headers/allowlist_fix.hpp similarity index 100% rename from tests/headers/allowlist_fix.hpp rename to bindgen-tests/tests/headers/allowlist_fix.hpp diff --git a/bindgen-tests/tests/headers/allowlist_item.h b/bindgen-tests/tests/headers/allowlist_item.h new file mode 100644 index 0000000000..7e5e00d0e3 --- /dev/null +++ b/bindgen-tests/tests/headers/allowlist_item.h @@ -0,0 +1,17 @@ +// bindgen-flags: --allowlist-item 'Foo.*' + +struct Foo { + int field; +}; + +struct Foo FooNew(int value); + +#define FooDefault 0 + +struct Bar { + int field; +}; + +struct Foo BarNew(int value); + +#define BarDefault 0 diff --git a/tests/headers/allowlist_vars.h b/bindgen-tests/tests/headers/allowlist_vars.h similarity index 100% rename from tests/headers/allowlist_vars.h rename to bindgen-tests/tests/headers/allowlist_vars.h diff --git a/bindgen-tests/tests/headers/allowlist_warnings.h b/bindgen-tests/tests/headers/allowlist_warnings.h new file mode 100644 index 0000000000..83c9e259f0 --- /dev/null +++ b/bindgen-tests/tests/headers/allowlist_warnings.h @@ -0,0 +1,2 @@ +// bindgen-flags: --allowlist-function "doesnt_match_anything" +int non_matched_function(int arg); diff --git a/tests/headers/allowlisted-item-references-no-hash.hpp b/bindgen-tests/tests/headers/allowlisted-item-references-no-hash.hpp similarity index 100% rename from tests/headers/allowlisted-item-references-no-hash.hpp rename to bindgen-tests/tests/headers/allowlisted-item-references-no-hash.hpp diff --git a/tests/headers/allowlisted-item-references-no-partialeq.hpp b/bindgen-tests/tests/headers/allowlisted-item-references-no-partialeq.hpp similarity index 100% rename from tests/headers/allowlisted-item-references-no-partialeq.hpp rename to bindgen-tests/tests/headers/allowlisted-item-references-no-partialeq.hpp diff --git a/tests/headers/allowlisted/file.hpp b/bindgen-tests/tests/headers/allowlisted/file.hpp similarity index 100% rename from tests/headers/allowlisted/file.hpp rename to bindgen-tests/tests/headers/allowlisted/file.hpp diff --git a/tests/headers/allowlisted_item_references_no_copy.hpp b/bindgen-tests/tests/headers/allowlisted_item_references_no_copy.hpp similarity index 100% rename from tests/headers/allowlisted_item_references_no_copy.hpp rename to bindgen-tests/tests/headers/allowlisted_item_references_no_copy.hpp diff --git a/tests/headers/annotation_hide.hpp b/bindgen-tests/tests/headers/annotation_hide.hpp similarity index 100% rename from tests/headers/annotation_hide.hpp rename to bindgen-tests/tests/headers/annotation_hide.hpp diff --git a/tests/headers/anon-fields-prefix.h b/bindgen-tests/tests/headers/anon-fields-prefix.h similarity index 100% rename from tests/headers/anon-fields-prefix.h rename to bindgen-tests/tests/headers/anon-fields-prefix.h diff --git a/tests/headers/anon_enum.hpp b/bindgen-tests/tests/headers/anon_enum.hpp similarity index 100% rename from tests/headers/anon_enum.hpp rename to bindgen-tests/tests/headers/anon_enum.hpp diff --git a/tests/headers/anon_enum_allowlist.h b/bindgen-tests/tests/headers/anon_enum_allowlist.h similarity index 100% rename from tests/headers/anon_enum_allowlist.h rename to bindgen-tests/tests/headers/anon_enum_allowlist.h diff --git a/bindgen-tests/tests/headers/anon_enum_allowlist_item.h b/bindgen-tests/tests/headers/anon_enum_allowlist_item.h new file mode 100644 index 0000000000..23caacc9a1 --- /dev/null +++ b/bindgen-tests/tests/headers/anon_enum_allowlist_item.h @@ -0,0 +1,6 @@ +// bindgen-flags: --allowlist-item "NODE_.*" + +enum { + NODE_FLAG_FOO, + NODE_FLAG_BAR, +}; diff --git a/bindgen-tests/tests/headers/anon_enum_blocklist.h b/bindgen-tests/tests/headers/anon_enum_blocklist.h new file mode 100644 index 0000000000..61aa6e680c --- /dev/null +++ b/bindgen-tests/tests/headers/anon_enum_blocklist.h @@ -0,0 +1,11 @@ +// bindgen-flags: --blocklist-type "_bindgen_ty_1" + +enum { + FLAG_X, + FLAG_Y, +}; + +enum { + FLAG_Z, + FLAG_W, +}; diff --git a/tests/headers/anon_enum_trait.hpp b/bindgen-tests/tests/headers/anon_enum_trait.hpp similarity index 100% rename from tests/headers/anon_enum_trait.hpp rename to bindgen-tests/tests/headers/anon_enum_trait.hpp diff --git a/tests/headers/anon_struct_in_union.h b/bindgen-tests/tests/headers/anon_struct_in_union.h similarity index 100% rename from tests/headers/anon_struct_in_union.h rename to bindgen-tests/tests/headers/anon_struct_in_union.h diff --git a/tests/headers/anon_union.hpp b/bindgen-tests/tests/headers/anon_union.hpp similarity index 100% rename from tests/headers/anon_union.hpp rename to bindgen-tests/tests/headers/anon_union.hpp diff --git a/tests/headers/anonymous-template-types.hpp b/bindgen-tests/tests/headers/anonymous-template-types.hpp similarity index 100% rename from tests/headers/anonymous-template-types.hpp rename to bindgen-tests/tests/headers/anonymous-template-types.hpp diff --git a/tests/headers/arg_keyword.hpp b/bindgen-tests/tests/headers/arg_keyword.hpp similarity index 100% rename from tests/headers/arg_keyword.hpp rename to bindgen-tests/tests/headers/arg_keyword.hpp diff --git a/tests/headers/array-of-zero-sized-types.hpp b/bindgen-tests/tests/headers/array-of-zero-sized-types.hpp similarity index 100% rename from tests/headers/array-of-zero-sized-types.hpp rename to bindgen-tests/tests/headers/array-of-zero-sized-types.hpp diff --git a/bindgen-tests/tests/headers/atomic-constant.h b/bindgen-tests/tests/headers/atomic-constant.h new file mode 100644 index 0000000000..b28f76f7e4 --- /dev/null +++ b/bindgen-tests/tests/headers/atomic-constant.h @@ -0,0 +1,2 @@ +_Atomic(int) a; +int b; diff --git a/bindgen-tests/tests/headers/attribute-custom-cli.h b/bindgen-tests/tests/headers/attribute-custom-cli.h new file mode 100644 index 0000000000..a5f73c78e5 --- /dev/null +++ b/bindgen-tests/tests/headers/attribute-custom-cli.h @@ -0,0 +1,14 @@ +// bindgen-flags: --default-enum-style rust --default-non-copy-union-style manually_drop --no-default=".*" --no-hash=".*" --no-partialeq=".*" --no-debug=".*" --no-copy=".*" --with-attribute-custom="foo_[^e].*=#[doc(hidden)]" --with-attribute-custom-struct="foo.*=#[derive(Default)]" --with-attribute-custom-enum="foo.*=#[cfg_attr(test, derive(PartialOrd, Copy))]" --with-attribute-custom-union="foo.*=#[derive(Clone)],#[derive(Copy)]" +struct foo_struct { + int inner; +}; +enum foo_enum { + inner = 0 +}; +union foo_union { + int fst; + float snd; +}; +struct non_matching { + int inner; +}; diff --git a/bindgen-tests/tests/headers/attribute-custom.h b/bindgen-tests/tests/headers/attribute-custom.h new file mode 100644 index 0000000000..dd382bf8cd --- /dev/null +++ b/bindgen-tests/tests/headers/attribute-custom.h @@ -0,0 +1,28 @@ +// bindgen-flags: --no-derive-debug --no-derive-copy --no-derive-default --default-enum-style rust --no-layout-tests + +/**

*/ +struct my_type; + +/**
*/ +struct my_type; + +struct my_type { + int a; +}; + +/** + *
+ *
+ */ +struct my_type2; + +struct my_type2 { + unsigned a; +}; + +/** + *
+ */ +struct my_type3 { + unsigned long a; +}; diff --git a/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp b/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp new file mode 100644 index 0000000000..bb9c3687e9 --- /dev/null +++ b/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp @@ -0,0 +1,10 @@ +// bindgen-flags: --enable-function-attribute-detection + +class Foo { +public: + __attribute__((warn_unused_result)) + int foo(int); +}; + +__attribute__((warn_unused_result)) +int foo(int); diff --git a/tests/headers/attribute_warn_unused_result_pre_1_27.hpp b/bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp similarity index 100% rename from tests/headers/attribute_warn_unused_result_pre_1_27.hpp rename to bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp diff --git a/tests/headers/auto.hpp b/bindgen-tests/tests/headers/auto.hpp similarity index 100% rename from tests/headers/auto.hpp rename to bindgen-tests/tests/headers/auto.hpp diff --git a/tests/headers/bad-namespace-parenthood-inheritance.hpp b/bindgen-tests/tests/headers/bad-namespace-parenthood-inheritance.hpp similarity index 100% rename from tests/headers/bad-namespace-parenthood-inheritance.hpp rename to bindgen-tests/tests/headers/bad-namespace-parenthood-inheritance.hpp diff --git a/tests/headers/base-to-derived.hpp b/bindgen-tests/tests/headers/base-to-derived.hpp similarity index 100% rename from tests/headers/base-to-derived.hpp rename to bindgen-tests/tests/headers/base-to-derived.hpp diff --git a/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp b/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp new file mode 100644 index 0000000000..4007e02566 --- /dev/null +++ b/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --enable-cxx-namespaces + +namespace foo { + union Bar { + int foo; + int bar; + }; +} diff --git a/tests/headers/bitfield-32bit-overflow.h b/bindgen-tests/tests/headers/bitfield-32bit-overflow.h similarity index 100% rename from tests/headers/bitfield-32bit-overflow.h rename to bindgen-tests/tests/headers/bitfield-32bit-overflow.h diff --git a/tests/headers/bitfield-enum-basic.hpp b/bindgen-tests/tests/headers/bitfield-enum-basic.hpp similarity index 100% rename from tests/headers/bitfield-enum-basic.hpp rename to bindgen-tests/tests/headers/bitfield-enum-basic.hpp diff --git a/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp b/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp new file mode 100644 index 0000000000..da5fc961dd --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --bitfield-enum "Foo" -- -std=c++11 + +enum Foo { + Bar = 1 << 1, + Baz = 1 << 2, + Duplicated = 1 << 2, + Negative = -3, +}; diff --git a/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp b/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp new file mode 100644 index 0000000000..1c58ff4eca --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --bitfield-enum "Foo" + +enum Foo { + Bar = 1 << 1, + Baz = 1 << 2, + Duplicated = 1 << 2, + Negative = -3, +}; diff --git a/tests/headers/bitfield-large.hpp b/bindgen-tests/tests/headers/bitfield-large.hpp similarity index 100% rename from tests/headers/bitfield-large.hpp rename to bindgen-tests/tests/headers/bitfield-large.hpp diff --git a/bindgen-tests/tests/headers/bitfield-linux-32.hpp b/bindgen-tests/tests/headers/bitfield-linux-32.hpp new file mode 100644 index 0000000000..71ee6a7e1d --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield-linux-32.hpp @@ -0,0 +1,9 @@ +// bindgen-flags: --no-layout-tests -- --target=i586-unknown-linux + +typedef unsigned long long uint64_t; + +struct Test { + uint64_t foo; + uint64_t x : 56; + uint64_t y : 8; +}; diff --git a/tests/headers/bitfield-method-same-name.hpp b/bindgen-tests/tests/headers/bitfield-method-same-name.hpp similarity index 100% rename from tests/headers/bitfield-method-same-name.hpp rename to bindgen-tests/tests/headers/bitfield-method-same-name.hpp 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/tests/headers/bitfield_align.h b/bindgen-tests/tests/headers/bitfield_align.h similarity index 100% rename from tests/headers/bitfield_align.h rename to bindgen-tests/tests/headers/bitfield_align.h diff --git a/bindgen-tests/tests/headers/bitfield_align_2.h b/bindgen-tests/tests/headers/bitfield_align_2.h new file mode 100644 index 0000000000..cb0f2e20d2 --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield_align_2.h @@ -0,0 +1,12 @@ +// bindgen-flags: --rustified-enum ".*" --raw-line '#![cfg(not(target_os="windows"))]' +enum MyEnum { + ONE, + TWO, + THREE, + FOUR +}; + +struct TaggedPtr { + enum MyEnum tag : 2; + long ptr : 62; +}; diff --git a/tests/headers/bitfield_large_overflow.hpp b/bindgen-tests/tests/headers/bitfield_large_overflow.hpp similarity index 100% rename from tests/headers/bitfield_large_overflow.hpp rename to bindgen-tests/tests/headers/bitfield_large_overflow.hpp diff --git a/tests/headers/bitfield_method_mangling.h b/bindgen-tests/tests/headers/bitfield_method_mangling.h similarity index 100% rename from tests/headers/bitfield_method_mangling.h rename to bindgen-tests/tests/headers/bitfield_method_mangling.h 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/bitfield_pragma_packed.h b/bindgen-tests/tests/headers/bitfield_pragma_packed.h new file mode 100644 index 0000000000..c18b80ddfc --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield_pragma_packed.h @@ -0,0 +1,20 @@ +#pragma pack(push, 1) +struct Struct { + unsigned char a : 1; + unsigned char b : 1; + unsigned char c : 6; + unsigned short int d : 16; + unsigned char e : 8; +}; +#pragma pack(pop) + +struct Inner { + unsigned short a: 16; + unsigned short b: 16; +}; + +#pragma pack(push, 1) +struct Outer { + struct Inner inner; +}; +#pragma pop diff --git a/tests/headers/block_return_type.h b/bindgen-tests/tests/headers/block_return_type.h similarity index 100% rename from tests/headers/block_return_type.h rename to bindgen-tests/tests/headers/block_return_type.h diff --git a/tests/headers/blocklist-and-impl-debug.hpp b/bindgen-tests/tests/headers/blocklist-and-impl-debug.hpp similarity index 100% rename from tests/headers/blocklist-and-impl-debug.hpp rename to bindgen-tests/tests/headers/blocklist-and-impl-debug.hpp diff --git a/tests/headers/blocklist-file.hpp b/bindgen-tests/tests/headers/blocklist-file.hpp similarity index 100% rename from tests/headers/blocklist-file.hpp rename to bindgen-tests/tests/headers/blocklist-file.hpp diff --git a/tests/headers/blocklist-function.hpp b/bindgen-tests/tests/headers/blocklist-function.hpp similarity index 100% rename from tests/headers/blocklist-function.hpp rename to bindgen-tests/tests/headers/blocklist-function.hpp diff --git a/tests/headers/blocklist-item.hpp b/bindgen-tests/tests/headers/blocklist-item.hpp similarity index 100% rename from tests/headers/blocklist-item.hpp rename to bindgen-tests/tests/headers/blocklist-item.hpp diff --git a/bindgen-tests/tests/headers/blocklist-methods.hpp b/bindgen-tests/tests/headers/blocklist-methods.hpp new file mode 100644 index 0000000000..4be21b945e --- /dev/null +++ b/bindgen-tests/tests/headers/blocklist-methods.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --blocklist-function="Foo_ba.*" + +class Foo { + public: + int foo(); + int bar(); + int baz(); +}; diff --git a/bindgen-tests/tests/headers/blocklist-var.hpp b/bindgen-tests/tests/headers/blocklist-var.hpp new file mode 100644 index 0000000000..3c70e6f032 --- /dev/null +++ b/bindgen-tests/tests/headers/blocklist-var.hpp @@ -0,0 +1,3 @@ +// bindgen-flags: --blocklist-var should_be_blocked + +extern int should_be_blocked; diff --git a/bindgen-tests/tests/headers/blocklist_bitfield_unit.h b/bindgen-tests/tests/headers/blocklist_bitfield_unit.h new file mode 100644 index 0000000000..5f7d94ced9 --- /dev/null +++ b/bindgen-tests/tests/headers/blocklist_bitfield_unit.h @@ -0,0 +1,7 @@ +// bindgen-flags: --blocklist-type "__BindgenBitfieldUnit" --raw-line '#[path = "./struct_with_bitfields.rs"] mod bitfields;' --raw-line 'use bitfields::*;' +struct C { + unsigned char x; + unsigned b1 : 1; + unsigned b2 : 1; + unsigned baz; +}; diff --git a/tests/headers/blocklisted/fake-stdint.h b/bindgen-tests/tests/headers/blocklisted/fake-stdint.h similarity index 100% rename from tests/headers/blocklisted/fake-stdint.h rename to bindgen-tests/tests/headers/blocklisted/fake-stdint.h diff --git a/tests/headers/blocklisted/file.hpp b/bindgen-tests/tests/headers/blocklisted/file.hpp similarity index 100% rename from tests/headers/blocklisted/file.hpp rename to bindgen-tests/tests/headers/blocklisted/file.hpp diff --git a/tests/headers/blocks-signature.hpp b/bindgen-tests/tests/headers/blocks-signature.hpp similarity index 100% rename from tests/headers/blocks-signature.hpp rename to bindgen-tests/tests/headers/blocks-signature.hpp diff --git a/tests/headers/blocks.hpp b/bindgen-tests/tests/headers/blocks.hpp similarity index 100% rename from tests/headers/blocks.hpp rename to bindgen-tests/tests/headers/blocks.hpp diff --git a/tests/headers/bug-1529681.hpp b/bindgen-tests/tests/headers/bug-1529681.hpp similarity index 100% rename from tests/headers/bug-1529681.hpp rename to bindgen-tests/tests/headers/bug-1529681.hpp diff --git a/tests/headers/builtin-template.hpp b/bindgen-tests/tests/headers/builtin-template.hpp similarity index 100% rename from tests/headers/builtin-template.hpp rename to bindgen-tests/tests/headers/builtin-template.hpp diff --git a/tests/headers/c-empty-layout.h b/bindgen-tests/tests/headers/c-empty-layout.h similarity index 100% rename from tests/headers/c-empty-layout.h rename to bindgen-tests/tests/headers/c-empty-layout.h diff --git a/bindgen-tests/tests/headers/c-unwind-abi-override.h b/bindgen-tests/tests/headers/c-unwind-abi-override.h new file mode 100644 index 0000000000..591f4b84ff --- /dev/null +++ b/bindgen-tests/tests/headers/c-unwind-abi-override.h @@ -0,0 +1,5 @@ +// bindgen-flags: --override-abi="foo|bar=C-unwind" + +void foo(); +void bar(); +void baz(); diff --git a/tests/headers/c_naming.h b/bindgen-tests/tests/headers/c_naming.h similarity index 100% rename from tests/headers/c_naming.h rename to bindgen-tests/tests/headers/c_naming.h diff --git a/tests/headers/call-conv-field.h b/bindgen-tests/tests/headers/call-conv-field.h similarity index 100% rename from tests/headers/call-conv-field.h rename to bindgen-tests/tests/headers/call-conv-field.h diff --git a/tests/headers/call-conv-typedef.h b/bindgen-tests/tests/headers/call-conv-typedef.h similarity index 100% rename from tests/headers/call-conv-typedef.h rename to bindgen-tests/tests/headers/call-conv-typedef.h diff --git a/tests/headers/canonical-types.hpp b/bindgen-tests/tests/headers/canonical-types.hpp similarity index 100% rename from tests/headers/canonical-types.hpp rename to bindgen-tests/tests/headers/canonical-types.hpp diff --git a/tests/headers/canonical_path_without_namespacing.hpp b/bindgen-tests/tests/headers/canonical_path_without_namespacing.hpp similarity index 100% rename from tests/headers/canonical_path_without_namespacing.hpp rename to bindgen-tests/tests/headers/canonical_path_without_namespacing.hpp diff --git a/tests/headers/char.h b/bindgen-tests/tests/headers/char.h similarity index 100% rename from tests/headers/char.h rename to bindgen-tests/tests/headers/char.h 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/tests/headers/class.hpp b/bindgen-tests/tests/headers/class.hpp similarity index 94% rename from tests/headers/class.hpp rename to bindgen-tests/tests/headers/class.hpp index a90e373f77..f77ac92a66 100644 --- a/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/tests/headers/class_nested.hpp b/bindgen-tests/tests/headers/class_nested.hpp similarity index 100% rename from tests/headers/class_nested.hpp rename to bindgen-tests/tests/headers/class_nested.hpp diff --git a/tests/headers/class_no_members.hpp b/bindgen-tests/tests/headers/class_no_members.hpp similarity index 100% rename from tests/headers/class_no_members.hpp rename to bindgen-tests/tests/headers/class_no_members.hpp diff --git a/tests/headers/class_static.hpp b/bindgen-tests/tests/headers/class_static.hpp similarity index 100% rename from tests/headers/class_static.hpp rename to bindgen-tests/tests/headers/class_static.hpp diff --git a/tests/headers/class_static_const.hpp b/bindgen-tests/tests/headers/class_static_const.hpp similarity index 100% rename from tests/headers/class_static_const.hpp rename to bindgen-tests/tests/headers/class_static_const.hpp diff --git a/tests/headers/class_use_as.hpp b/bindgen-tests/tests/headers/class_use_as.hpp similarity index 100% rename from tests/headers/class_use_as.hpp rename to bindgen-tests/tests/headers/class_use_as.hpp diff --git a/tests/headers/class_with_dtor.hpp b/bindgen-tests/tests/headers/class_with_dtor.hpp similarity index 100% rename from tests/headers/class_with_dtor.hpp rename to bindgen-tests/tests/headers/class_with_dtor.hpp 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/tests/headers/class_with_inner_struct.hpp b/bindgen-tests/tests/headers/class_with_inner_struct.hpp similarity index 100% rename from tests/headers/class_with_inner_struct.hpp rename to bindgen-tests/tests/headers/class_with_inner_struct.hpp diff --git a/tests/headers/class_with_typedef.hpp b/bindgen-tests/tests/headers/class_with_typedef.hpp similarity index 100% rename from tests/headers/class_with_typedef.hpp rename to bindgen-tests/tests/headers/class_with_typedef.hpp diff --git a/tests/headers/comment-indent.hpp b/bindgen-tests/tests/headers/comment-indent.hpp similarity index 100% rename from tests/headers/comment-indent.hpp rename to bindgen-tests/tests/headers/comment-indent.hpp diff --git a/tests/headers/complex.h b/bindgen-tests/tests/headers/complex.h similarity index 100% rename from tests/headers/complex.h rename to bindgen-tests/tests/headers/complex.h diff --git a/tests/headers/complex_global.h b/bindgen-tests/tests/headers/complex_global.h similarity index 100% rename from tests/headers/complex_global.h rename to bindgen-tests/tests/headers/complex_global.h diff --git a/tests/headers/const-const-mut-ptr.h b/bindgen-tests/tests/headers/const-const-mut-ptr.h similarity index 100% rename from tests/headers/const-const-mut-ptr.h rename to bindgen-tests/tests/headers/const-const-mut-ptr.h diff --git a/tests/headers/const_array.h b/bindgen-tests/tests/headers/const_array.h similarity index 100% rename from tests/headers/const_array.h rename to bindgen-tests/tests/headers/const_array.h diff --git a/tests/headers/const_array_fn_arg.h b/bindgen-tests/tests/headers/const_array_fn_arg.h similarity index 100% rename from tests/headers/const_array_fn_arg.h rename to bindgen-tests/tests/headers/const_array_fn_arg.h diff --git a/bindgen-tests/tests/headers/const_array_typedef.h b/bindgen-tests/tests/headers/const_array_typedef.h new file mode 100644 index 0000000000..e5379c97ba --- /dev/null +++ b/bindgen-tests/tests/headers/const_array_typedef.h @@ -0,0 +1,13 @@ +typedef struct { + int field; +} strct; + +typedef strct typ[1]; + +extern typ w; +extern strct *x; + +extern const typ y; +extern const strct *z; + +void function(const typ a, const strct *b); diff --git a/tests/headers/const_bool.hpp b/bindgen-tests/tests/headers/const_bool.hpp similarity index 100% rename from tests/headers/const_bool.hpp rename to bindgen-tests/tests/headers/const_bool.hpp diff --git a/tests/headers/const_enum_unnamed.hpp b/bindgen-tests/tests/headers/const_enum_unnamed.hpp similarity index 100% rename from tests/headers/const_enum_unnamed.hpp rename to bindgen-tests/tests/headers/const_enum_unnamed.hpp diff --git a/tests/headers/const_multidim_array_fn_arg.h b/bindgen-tests/tests/headers/const_multidim_array_fn_arg.h similarity index 100% rename from tests/headers/const_multidim_array_fn_arg.h rename to bindgen-tests/tests/headers/const_multidim_array_fn_arg.h diff --git a/tests/headers/const_ptr.hpp b/bindgen-tests/tests/headers/const_ptr.hpp similarity index 100% rename from tests/headers/const_ptr.hpp rename to bindgen-tests/tests/headers/const_ptr.hpp diff --git a/tests/headers/const_resolved_ty.h b/bindgen-tests/tests/headers/const_resolved_ty.h similarity index 100% rename from tests/headers/const_resolved_ty.h rename to bindgen-tests/tests/headers/const_resolved_ty.h diff --git a/tests/headers/const_tparam.hpp b/bindgen-tests/tests/headers/const_tparam.hpp similarity index 100% rename from tests/headers/const_tparam.hpp rename to bindgen-tests/tests/headers/const_tparam.hpp diff --git a/tests/headers/constant-evaluate.h b/bindgen-tests/tests/headers/constant-evaluate.h similarity index 100% rename from tests/headers/constant-evaluate.h rename to bindgen-tests/tests/headers/constant-evaluate.h diff --git a/tests/headers/constant-non-specialized-tp.hpp b/bindgen-tests/tests/headers/constant-non-specialized-tp.hpp similarity index 100% rename from tests/headers/constant-non-specialized-tp.hpp rename to bindgen-tests/tests/headers/constant-non-specialized-tp.hpp diff --git a/tests/headers/constified-enum-module-overflow.hpp b/bindgen-tests/tests/headers/constified-enum-module-overflow.hpp similarity index 100% rename from tests/headers/constified-enum-module-overflow.hpp rename to bindgen-tests/tests/headers/constified-enum-module-overflow.hpp diff --git a/tests/headers/constify-all-enums.h b/bindgen-tests/tests/headers/constify-all-enums.h similarity index 100% rename from tests/headers/constify-all-enums.h rename to bindgen-tests/tests/headers/constify-all-enums.h diff --git a/tests/headers/constify-enum.h b/bindgen-tests/tests/headers/constify-enum.h similarity index 100% rename from tests/headers/constify-enum.h rename to bindgen-tests/tests/headers/constify-enum.h diff --git a/tests/headers/constify-module-enums-basic.h b/bindgen-tests/tests/headers/constify-module-enums-basic.h similarity index 100% rename from tests/headers/constify-module-enums-basic.h rename to bindgen-tests/tests/headers/constify-module-enums-basic.h diff --git a/tests/headers/constify-module-enums-namespace.hpp b/bindgen-tests/tests/headers/constify-module-enums-namespace.hpp similarity index 100% rename from tests/headers/constify-module-enums-namespace.hpp rename to bindgen-tests/tests/headers/constify-module-enums-namespace.hpp diff --git a/tests/headers/constify-module-enums-shadow-name.h b/bindgen-tests/tests/headers/constify-module-enums-shadow-name.h similarity index 100% rename from tests/headers/constify-module-enums-shadow-name.h rename to bindgen-tests/tests/headers/constify-module-enums-shadow-name.h diff --git a/tests/headers/constify-module-enums-simple-alias.hpp b/bindgen-tests/tests/headers/constify-module-enums-simple-alias.hpp similarity index 100% rename from tests/headers/constify-module-enums-simple-alias.hpp rename to bindgen-tests/tests/headers/constify-module-enums-simple-alias.hpp diff --git a/tests/headers/constify-module-enums-simple-nonamespace.hpp b/bindgen-tests/tests/headers/constify-module-enums-simple-nonamespace.hpp similarity index 100% rename from tests/headers/constify-module-enums-simple-nonamespace.hpp rename to bindgen-tests/tests/headers/constify-module-enums-simple-nonamespace.hpp diff --git a/tests/headers/constify-module-enums-types.hpp b/bindgen-tests/tests/headers/constify-module-enums-types.hpp similarity index 92% rename from tests/headers/constify-module-enums-types.hpp rename to bindgen-tests/tests/headers/constify-module-enums-types.hpp index decf935a00..96bed18f4b 100644 --- a/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/tests/headers/constructor-tp.hpp b/bindgen-tests/tests/headers/constructor-tp.hpp similarity index 91% rename from tests/headers/constructor-tp.hpp rename to bindgen-tests/tests/headers/constructor-tp.hpp index 6e55ea7852..3b5d54071a 100644 --- a/tests/headers/constructor-tp.hpp +++ b/bindgen-tests/tests/headers/constructor-tp.hpp @@ -8,7 +8,7 @@ class Foo { }; template -inline void +void Foo::doBaz() { } @@ -21,6 +21,5 @@ template Foo::Foo() { } -inline Bar::Bar() { } diff --git a/tests/headers/constructors.hpp b/bindgen-tests/tests/headers/constructors.hpp similarity index 80% rename from tests/headers/constructors.hpp rename to bindgen-tests/tests/headers/constructors.hpp index d417488917..2f8d57b00b 100644 --- a/tests/headers/constructors.hpp +++ b/bindgen-tests/tests/headers/constructors.hpp @@ -1,6 +1,6 @@ class TestOverload { - // This one shouldnt' be generated. + // This one shouldn't be generated. TestOverload(); public: TestOverload(int); diff --git a/tests/headers/constructors_1_33.hpp b/bindgen-tests/tests/headers/constructors_1_33.hpp similarity index 83% rename from tests/headers/constructors_1_33.hpp rename to bindgen-tests/tests/headers/constructors_1_33.hpp index 7c6262d417..b16c8c35a3 100644 --- a/tests/headers/constructors_1_33.hpp +++ b/bindgen-tests/tests/headers/constructors_1_33.hpp @@ -1,7 +1,5 @@ -// bindgen-flags: --rust-target 1.33 - class TestOverload { - // This one shouldnt' be generated. + // This one shouldn't be generated. TestOverload(); public: /// Calling this should use `mem::unintialized()` and not `MaybeUninit()` as only rust 1.36 includes that. diff --git a/tests/headers/contains-vs-inherits-zero-sized.hpp b/bindgen-tests/tests/headers/contains-vs-inherits-zero-sized.hpp similarity index 100% rename from tests/headers/contains-vs-inherits-zero-sized.hpp rename to bindgen-tests/tests/headers/contains-vs-inherits-zero-sized.hpp diff --git a/tests/headers/convert-cpp-comment-to-rust.hpp b/bindgen-tests/tests/headers/convert-cpp-comment-to-rust.hpp similarity index 88% rename from tests/headers/convert-cpp-comment-to-rust.hpp rename to bindgen-tests/tests/headers/convert-cpp-comment-to-rust.hpp index 649c236538..f5bbbf58b2 100644 --- a/tests/headers/convert-cpp-comment-to-rust.hpp +++ b/bindgen-tests/tests/headers/convert-cpp-comment-to-rust.hpp @@ -1,4 +1,4 @@ - +// bindgen-flags: --no-layout-tests typedef unsigned mbedtls_mpi_uint; /** diff --git a/tests/headers/convert-floats.h b/bindgen-tests/tests/headers/convert-floats.h similarity index 100% rename from tests/headers/convert-floats.h rename to bindgen-tests/tests/headers/convert-floats.h diff --git a/bindgen-tests/tests/headers/core_ffi_c.h b/bindgen-tests/tests/headers/core_ffi_c.h new file mode 100644 index 0000000000..6df1e2f87a --- /dev/null +++ b/bindgen-tests/tests/headers/core_ffi_c.h @@ -0,0 +1,14 @@ +// bindgen-flags: --use-core --rust-target 1.64 --no-convert-floats +typedef char c_char; +typedef double c_double; +typedef float c_float; +typedef int c_int; +typedef long c_long; +typedef long long c_longlong; +typedef signed char c_schar; +typedef short c_short; +typedef unsigned char c_uchar; +typedef unsigned int c_uint; +typedef unsigned long c_ulong; +typedef unsigned long long c_ulonglong; +typedef unsigned short c_ushort; diff --git a/tests/headers/cpp-empty-layout.hpp b/bindgen-tests/tests/headers/cpp-empty-layout.hpp similarity index 100% rename from tests/headers/cpp-empty-layout.hpp rename to bindgen-tests/tests/headers/cpp-empty-layout.hpp diff --git a/tests/headers/crtp.hpp b/bindgen-tests/tests/headers/crtp.hpp similarity index 100% rename from tests/headers/crtp.hpp rename to bindgen-tests/tests/headers/crtp.hpp diff --git a/tests/headers/ctypes-prefix-path.h b/bindgen-tests/tests/headers/ctypes-prefix-path.h similarity index 100% rename from tests/headers/ctypes-prefix-path.h rename to bindgen-tests/tests/headers/ctypes-prefix-path.h diff --git a/tests/headers/dash_language.h b/bindgen-tests/tests/headers/dash_language.h similarity index 100% rename from tests/headers/dash_language.h rename to bindgen-tests/tests/headers/dash_language.h diff --git a/tests/headers/decl_extern_int_twice.h b/bindgen-tests/tests/headers/decl_extern_int_twice.h similarity index 100% rename from tests/headers/decl_extern_int_twice.h rename to bindgen-tests/tests/headers/decl_extern_int_twice.h diff --git a/tests/headers/decl_ptr_to_array.h b/bindgen-tests/tests/headers/decl_ptr_to_array.h similarity index 100% rename from tests/headers/decl_ptr_to_array.h rename to bindgen-tests/tests/headers/decl_ptr_to_array.h diff --git a/tests/headers/default-enum-style-constified-module.h b/bindgen-tests/tests/headers/default-enum-style-constified-module.h similarity index 100% rename from tests/headers/default-enum-style-constified-module.h rename to bindgen-tests/tests/headers/default-enum-style-constified-module.h diff --git a/tests/headers/default-macro-constant-type-signed.h b/bindgen-tests/tests/headers/default-macro-constant-type-signed.h similarity index 100% rename from tests/headers/default-macro-constant-type-signed.h rename to bindgen-tests/tests/headers/default-macro-constant-type-signed.h diff --git a/tests/headers/default-macro-constant-type-unsigned.h b/bindgen-tests/tests/headers/default-macro-constant-type-unsigned.h similarity index 100% rename from tests/headers/default-macro-constant-type-unsigned.h rename to bindgen-tests/tests/headers/default-macro-constant-type-unsigned.h diff --git a/tests/headers/default-macro-constant-type.h b/bindgen-tests/tests/headers/default-macro-constant-type.h similarity index 100% rename from tests/headers/default-macro-constant-type.h rename to bindgen-tests/tests/headers/default-macro-constant-type.h diff --git a/tests/headers/default-template-parameter.hpp b/bindgen-tests/tests/headers/default-template-parameter.hpp similarity index 100% rename from tests/headers/default-template-parameter.hpp rename to bindgen-tests/tests/headers/default-template-parameter.hpp diff --git a/bindgen-tests/tests/headers/default_visibility_crate.h b/bindgen-tests/tests/headers/default_visibility_crate.h new file mode 100644 index 0000000000..c6f0be87c5 --- /dev/null +++ b/bindgen-tests/tests/headers/default_visibility_crate.h @@ -0,0 +1,12 @@ +// bindgen-flags: --no-layout-tests --default-visibility=crate + +struct Point { + int x; + int y; +}; + +struct Color { + char r :1; + char g :1; + char b :1; +}; diff --git a/bindgen-tests/tests/headers/default_visibility_private.h b/bindgen-tests/tests/headers/default_visibility_private.h new file mode 100644 index 0000000000..7ba75f7cb8 --- /dev/null +++ b/bindgen-tests/tests/headers/default_visibility_private.h @@ -0,0 +1,12 @@ +// bindgen-flags: --no-layout-tests --default-visibility=private + +struct Point { + int x; + int y; +}; + +struct Color { + char r :1; + char g :1; + char b :1; +}; diff --git a/bindgen-tests/tests/headers/default_visibility_private_respects_cxx_access_spec.h b/bindgen-tests/tests/headers/default_visibility_private_respects_cxx_access_spec.h new file mode 100644 index 0000000000..875484099a --- /dev/null +++ b/bindgen-tests/tests/headers/default_visibility_private_respects_cxx_access_spec.h @@ -0,0 +1,12 @@ +// bindgen-flags: --respect-cxx-access-specs --no-layout-tests --default-visibility=private + +struct Point { + int x; + int y; +}; + +struct Color { + char r :1; + char g :1; + char b :1; +}; diff --git a/tests/headers/deleted-function.hpp b/bindgen-tests/tests/headers/deleted-function.hpp similarity index 100% rename from tests/headers/deleted-function.hpp rename to bindgen-tests/tests/headers/deleted-function.hpp diff --git a/tests/headers/derive-bitfield-method-same-name.hpp b/bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp similarity index 93% rename from tests/headers/derive-bitfield-method-same-name.hpp rename to bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp index ea9d801f4e..4b7b21e93a 100644 --- a/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 new file mode 100644 index 0000000000..8dc30eacfc --- /dev/null +++ b/bindgen-tests/tests/headers/derive-clone.h @@ -0,0 +1,4 @@ +/// This struct should derive `Clone`. +struct ShouldDeriveClone { + int large[33]; +}; diff --git a/bindgen-tests/tests/headers/derive-custom-cli.h b/bindgen-tests/tests/headers/derive-custom-cli.h new file mode 100644 index 0000000000..9b65536f94 --- /dev/null +++ b/bindgen-tests/tests/headers/derive-custom-cli.h @@ -0,0 +1,14 @@ +// bindgen-flags: --default-enum-style rust --default-non-copy-union-style manually_drop --no-default=".*" --no-hash=".*" --no-partialeq=".*" --no-debug=".*" --no-copy=".*" --with-derive-custom="foo_[^e].*=Clone" --with-derive-custom-struct="foo.*=Default" --with-derive-custom-enum="foo.*=Copy" --with-derive-custom-union="foo.*=Copy" +struct foo_struct { + int inner; +}; +enum foo_enum { + inner = 0 +}; +union foo_union { + int fst; + float snd; +}; +struct non_matching { + int inner; +}; diff --git a/tests/headers/derive-custom.h b/bindgen-tests/tests/headers/derive-custom.h similarity index 93% rename from tests/headers/derive-custom.h rename to bindgen-tests/tests/headers/derive-custom.h index 83f2ce08a9..8c57278cb3 100644 --- a/tests/headers/derive-custom.h +++ b/bindgen-tests/tests/headers/derive-custom.h @@ -1,4 +1,4 @@ -// bindgen-flags: --no-derive-debug --no-derive-copy --default-enum-style rust +// bindgen-flags: --no-derive-debug --no-derive-copy --default-enum-style rust --no-layout-tests /**
*/ struct my_type; 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/tests/headers/derive-debug-bitfield-core.hpp b/bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp similarity index 81% rename from tests/headers/derive-debug-bitfield-core.hpp rename to bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp index 2073cc2a0d..5d78e74359 100644 --- a/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 new file mode 100644 index 0000000000..df43e6a7c2 --- /dev/null +++ b/bindgen-tests/tests/headers/derive-debug-bitfield.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-function-pointer.hpp b/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp new file mode 100644 index 0000000000..a370dee813 --- /dev/null +++ b/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --impl-debug + +class Nice { + typedef void (*Function) (int data); + Function pointer; + int large_array[34]; +}; diff --git a/bindgen-tests/tests/headers/derive-debug-generic.hpp b/bindgen-tests/tests/headers/derive-debug-generic.hpp new file mode 100644 index 0000000000..d5158510ea --- /dev/null +++ b/bindgen-tests/tests/headers/derive-debug-generic.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --impl-debug + +template +class Generic { + T t[40]; +}; diff --git a/tests/headers/derive-debug-mangle-name.h b/bindgen-tests/tests/headers/derive-debug-mangle-name.h similarity index 100% rename from tests/headers/derive-debug-mangle-name.h rename to bindgen-tests/tests/headers/derive-debug-mangle-name.h diff --git a/tests/headers/derive-debug-opaque-template-instantiation.hpp b/bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp similarity index 80% rename from tests/headers/derive-debug-opaque-template-instantiation.hpp rename to bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp index 0c70fcc53a..0dead782ff 100644 --- a/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 new file mode 100644 index 0000000000..0ce1d63ab8 --- /dev/null +++ b/bindgen-tests/tests/headers/derive-debug-opaque.hpp @@ -0,0 +1,10 @@ +// bindgen-flags: --opaque-type "Opaque" --impl-debug + +class Opaque { + int i; + int not_debug[40]; +}; + +class OpaqueUser { + Opaque opaque; +}; diff --git a/tests/headers/derive-default-and-blocklist.hpp b/bindgen-tests/tests/headers/derive-default-and-blocklist.hpp similarity index 100% rename from tests/headers/derive-default-and-blocklist.hpp rename to bindgen-tests/tests/headers/derive-default-and-blocklist.hpp diff --git a/tests/headers/derive-fn-ptr.h b/bindgen-tests/tests/headers/derive-fn-ptr.h similarity index 100% rename from tests/headers/derive-fn-ptr.h rename to bindgen-tests/tests/headers/derive-fn-ptr.h diff --git a/tests/headers/derive-hash-and-blocklist.hpp b/bindgen-tests/tests/headers/derive-hash-and-blocklist.hpp similarity index 100% rename from tests/headers/derive-hash-and-blocklist.hpp rename to bindgen-tests/tests/headers/derive-hash-and-blocklist.hpp diff --git a/tests/headers/derive-hash-blocklisting.hpp b/bindgen-tests/tests/headers/derive-hash-blocklisting.hpp similarity index 100% rename from tests/headers/derive-hash-blocklisting.hpp rename to bindgen-tests/tests/headers/derive-hash-blocklisting.hpp diff --git a/tests/headers/derive-hash-struct-with-anon-struct-float.h b/bindgen-tests/tests/headers/derive-hash-struct-with-anon-struct-float.h similarity index 100% rename from tests/headers/derive-hash-struct-with-anon-struct-float.h rename to bindgen-tests/tests/headers/derive-hash-struct-with-anon-struct-float.h diff --git a/tests/headers/derive-hash-struct-with-float-array.h b/bindgen-tests/tests/headers/derive-hash-struct-with-float-array.h similarity index 100% rename from tests/headers/derive-hash-struct-with-float-array.h rename to bindgen-tests/tests/headers/derive-hash-struct-with-float-array.h diff --git a/tests/headers/derive-hash-struct-with-incomplete-array.h b/bindgen-tests/tests/headers/derive-hash-struct-with-incomplete-array.h similarity index 100% rename from tests/headers/derive-hash-struct-with-incomplete-array.h rename to bindgen-tests/tests/headers/derive-hash-struct-with-incomplete-array.h diff --git a/tests/headers/derive-hash-struct-with-pointer.h b/bindgen-tests/tests/headers/derive-hash-struct-with-pointer.h similarity index 100% rename from tests/headers/derive-hash-struct-with-pointer.h rename to bindgen-tests/tests/headers/derive-hash-struct-with-pointer.h diff --git a/tests/headers/derive-hash-template-def-float.hpp b/bindgen-tests/tests/headers/derive-hash-template-def-float.hpp similarity index 100% rename from tests/headers/derive-hash-template-def-float.hpp rename to bindgen-tests/tests/headers/derive-hash-template-def-float.hpp diff --git a/tests/headers/derive-hash-template-inst-float.hpp b/bindgen-tests/tests/headers/derive-hash-template-inst-float.hpp similarity index 100% rename from tests/headers/derive-hash-template-inst-float.hpp rename to bindgen-tests/tests/headers/derive-hash-template-inst-float.hpp diff --git a/tests/headers/derive-partialeq-and-blocklist.hpp b/bindgen-tests/tests/headers/derive-partialeq-and-blocklist.hpp similarity index 100% rename from tests/headers/derive-partialeq-and-blocklist.hpp rename to bindgen-tests/tests/headers/derive-partialeq-and-blocklist.hpp diff --git a/tests/headers/derive-partialeq-anonfield.h b/bindgen-tests/tests/headers/derive-partialeq-anonfield.h similarity index 100% rename from tests/headers/derive-partialeq-anonfield.h rename to bindgen-tests/tests/headers/derive-partialeq-anonfield.h diff --git a/bindgen-tests/tests/headers/derive-partialeq-base.hpp b/bindgen-tests/tests/headers/derive-partialeq-base.hpp new file mode 100644 index 0000000000..989cbe693a --- /dev/null +++ b/bindgen-tests/tests/headers/derive-partialeq-base.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --with-derive-partialeq --impl-partialeq + +class Base { + int large[33]; +}; + +class ShouldDerivePartialEq: Base { +}; diff --git a/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp b/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp new file mode 100644 index 0000000000..ac2cac632a --- /dev/null +++ b/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --with-derive-partialeq --impl-partialeq + +class C { + bool a: 1; + bool b: 7; + int large_array[50]; +}; diff --git a/bindgen-tests/tests/headers/derive-partialeq-core.h b/bindgen-tests/tests/headers/derive-partialeq-core.h new file mode 100644 index 0000000000..6da5b786bc --- /dev/null +++ b/bindgen-tests/tests/headers/derive-partialeq-core.h @@ -0,0 +1,5 @@ +// bindgen-flags: --with-derive-partialeq --impl-partialeq --use-core --raw-line "extern crate core;" + +struct C { + int large_array[420]; +}; diff --git a/tests/headers/derive-partialeq-pointer.hpp b/bindgen-tests/tests/headers/derive-partialeq-pointer.hpp similarity index 100% rename from tests/headers/derive-partialeq-pointer.hpp rename to bindgen-tests/tests/headers/derive-partialeq-pointer.hpp diff --git a/tests/headers/derive-partialeq-union.hpp b/bindgen-tests/tests/headers/derive-partialeq-union.hpp similarity index 100% rename from tests/headers/derive-partialeq-union.hpp rename to bindgen-tests/tests/headers/derive-partialeq-union.hpp diff --git a/tests/headers/disable-namespacing.hpp b/bindgen-tests/tests/headers/disable-namespacing.hpp similarity index 100% rename from tests/headers/disable-namespacing.hpp rename to bindgen-tests/tests/headers/disable-namespacing.hpp diff --git a/tests/headers/disable-nested-struct-naming.h b/bindgen-tests/tests/headers/disable-nested-struct-naming.h similarity index 100% rename from tests/headers/disable-nested-struct-naming.h rename to bindgen-tests/tests/headers/disable-nested-struct-naming.h diff --git a/tests/headers/disable-untagged-union.hpp b/bindgen-tests/tests/headers/disable-untagged-union.hpp similarity index 100% rename from tests/headers/disable-untagged-union.hpp rename to bindgen-tests/tests/headers/disable-untagged-union.hpp diff --git a/tests/headers/divide-by-zero-in-struct-layout.h b/bindgen-tests/tests/headers/divide-by-zero-in-struct-layout.h similarity index 100% rename from tests/headers/divide-by-zero-in-struct-layout.h rename to bindgen-tests/tests/headers/divide-by-zero-in-struct-layout.h diff --git a/tests/headers/do-not-derive-copy.hpp b/bindgen-tests/tests/headers/do-not-derive-copy.hpp similarity index 100% rename from tests/headers/do-not-derive-copy.hpp rename to bindgen-tests/tests/headers/do-not-derive-copy.hpp diff --git a/tests/headers/doggo-or-null.hpp b/bindgen-tests/tests/headers/doggo-or-null.hpp similarity index 100% rename from tests/headers/doggo-or-null.hpp rename to bindgen-tests/tests/headers/doggo-or-null.hpp diff --git a/tests/headers/dupe-enum-variant-in-namespace.h b/bindgen-tests/tests/headers/dupe-enum-variant-in-namespace.h similarity index 100% rename from tests/headers/dupe-enum-variant-in-namespace.h rename to bindgen-tests/tests/headers/dupe-enum-variant-in-namespace.h diff --git a/bindgen-tests/tests/headers/duplicated-definition-count.hpp b/bindgen-tests/tests/headers/duplicated-definition-count.hpp new file mode 100644 index 0000000000..2916762617 --- /dev/null +++ b/bindgen-tests/tests/headers/duplicated-definition-count.hpp @@ -0,0 +1,6 @@ +class BitStream { + public: + void Write(const char *inputByteArray, unsigned int numberOfBytes); + void Write(BitStream *bitStream, unsigned numberOfBits); + void Write1(); +}; diff --git a/tests/headers/duplicated-namespaces-definitions.hpp b/bindgen-tests/tests/headers/duplicated-namespaces-definitions.hpp similarity index 100% rename from tests/headers/duplicated-namespaces-definitions.hpp rename to bindgen-tests/tests/headers/duplicated-namespaces-definitions.hpp diff --git a/tests/headers/duplicated-namespaces.hpp b/bindgen-tests/tests/headers/duplicated-namespaces.hpp similarity index 100% rename from tests/headers/duplicated-namespaces.hpp rename to bindgen-tests/tests/headers/duplicated-namespaces.hpp diff --git a/tests/headers/duplicated_constants_in_ns.hpp b/bindgen-tests/tests/headers/duplicated_constants_in_ns.hpp similarity index 100% rename from tests/headers/duplicated_constants_in_ns.hpp rename to bindgen-tests/tests/headers/duplicated_constants_in_ns.hpp diff --git a/bindgen-tests/tests/headers/dynamic_loading_attributes.h b/bindgen-tests/tests/headers/dynamic_loading_attributes.h new file mode 100644 index 0000000000..e2ca62b159 --- /dev/null +++ b/bindgen-tests/tests/headers/dynamic_loading_attributes.h @@ -0,0 +1,11 @@ +// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all --enable-function-attribute-detection +/** + * @brief A function + * + * @param x + * @param y + * @return int + */ +__attribute__((warn_unused_result)) +int foo(int x, int y); +int baz() ; diff --git a/tests/headers/dynamic_loading_required.h b/bindgen-tests/tests/headers/dynamic_loading_required.h similarity index 100% rename from tests/headers/dynamic_loading_required.h rename to bindgen-tests/tests/headers/dynamic_loading_required.h diff --git a/tests/headers/dynamic_loading_simple.h b/bindgen-tests/tests/headers/dynamic_loading_simple.h similarity index 100% rename from tests/headers/dynamic_loading_simple.h rename to bindgen-tests/tests/headers/dynamic_loading_simple.h diff --git a/tests/headers/dynamic_loading_template.hpp b/bindgen-tests/tests/headers/dynamic_loading_template.hpp similarity index 100% rename from tests/headers/dynamic_loading_template.hpp rename to bindgen-tests/tests/headers/dynamic_loading_template.hpp diff --git a/bindgen-tests/tests/headers/dynamic_loading_variable_required.h b/bindgen-tests/tests/headers/dynamic_loading_variable_required.h new file mode 100644 index 0000000000..8e811bb320 --- /dev/null +++ b/bindgen-tests/tests/headers/dynamic_loading_variable_required.h @@ -0,0 +1,4 @@ +// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all + +int foo; +int *baz; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/dynamic_loading_variable_simple.h b/bindgen-tests/tests/headers/dynamic_loading_variable_simple.h new file mode 100644 index 0000000000..5ecad752ed --- /dev/null +++ b/bindgen-tests/tests/headers/dynamic_loading_variable_simple.h @@ -0,0 +1,4 @@ +// bindgen-flags: --dynamic-loading TestLib + +int foo; +int *baz; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/dynamic_loading_variable_with_allowlist.hpp b/bindgen-tests/tests/headers/dynamic_loading_variable_with_allowlist.hpp new file mode 100644 index 0000000000..5e27303063 --- /dev/null +++ b/bindgen-tests/tests/headers/dynamic_loading_variable_with_allowlist.hpp @@ -0,0 +1,5 @@ +// bindgen-flags: --dynamic-loading TestLib --allowlist-var foo --allowlist-var bar + +int foo; +int bar; +int baz; // should not be allowed \ No newline at end of file diff --git a/tests/headers/dynamic_loading_with_allowlist.hpp b/bindgen-tests/tests/headers/dynamic_loading_with_allowlist.hpp similarity index 100% rename from tests/headers/dynamic_loading_with_allowlist.hpp rename to bindgen-tests/tests/headers/dynamic_loading_with_allowlist.hpp diff --git a/tests/headers/dynamic_loading_with_blocklist.hpp b/bindgen-tests/tests/headers/dynamic_loading_with_blocklist.hpp similarity index 100% rename from tests/headers/dynamic_loading_with_blocklist.hpp rename to bindgen-tests/tests/headers/dynamic_loading_with_blocklist.hpp diff --git a/tests/headers/dynamic_loading_with_class.hpp b/bindgen-tests/tests/headers/dynamic_loading_with_class.hpp similarity index 100% rename from tests/headers/dynamic_loading_with_class.hpp rename to bindgen-tests/tests/headers/dynamic_loading_with_class.hpp diff --git a/tests/headers/elaborated.hpp b/bindgen-tests/tests/headers/elaborated.hpp similarity index 100% rename from tests/headers/elaborated.hpp rename to bindgen-tests/tests/headers/elaborated.hpp diff --git a/tests/headers/empty-enum.h b/bindgen-tests/tests/headers/empty-enum.h similarity index 100% rename from tests/headers/empty-enum.h rename to bindgen-tests/tests/headers/empty-enum.h diff --git a/bindgen-tests/tests/headers/empty-union.hpp b/bindgen-tests/tests/headers/empty-union.hpp new file mode 100644 index 0000000000..113a95ee30 --- /dev/null +++ b/bindgen-tests/tests/headers/empty-union.hpp @@ -0,0 +1,5 @@ +// bindgen-flags: --opaque-type ".*" + +template class a { + union {}; +}; diff --git a/tests/headers/empty_template_param_name.hpp b/bindgen-tests/tests/headers/empty_template_param_name.hpp similarity index 100% rename from tests/headers/empty_template_param_name.hpp rename to bindgen-tests/tests/headers/empty_template_param_name.hpp diff --git a/tests/headers/enum-default-bitfield.h b/bindgen-tests/tests/headers/enum-default-bitfield.h similarity index 100% rename from tests/headers/enum-default-bitfield.h rename to bindgen-tests/tests/headers/enum-default-bitfield.h diff --git a/tests/headers/enum-default-consts.h b/bindgen-tests/tests/headers/enum-default-consts.h similarity index 100% rename from tests/headers/enum-default-consts.h rename to bindgen-tests/tests/headers/enum-default-consts.h diff --git a/tests/headers/enum-default-module.h b/bindgen-tests/tests/headers/enum-default-module.h similarity index 100% rename from tests/headers/enum-default-module.h rename to bindgen-tests/tests/headers/enum-default-module.h diff --git a/tests/headers/enum-default-rust.h b/bindgen-tests/tests/headers/enum-default-rust.h similarity index 100% rename from tests/headers/enum-default-rust.h rename to bindgen-tests/tests/headers/enum-default-rust.h diff --git a/tests/headers/enum-doc-bitfield.h b/bindgen-tests/tests/headers/enum-doc-bitfield.h similarity index 100% rename from tests/headers/enum-doc-bitfield.h rename to bindgen-tests/tests/headers/enum-doc-bitfield.h diff --git a/tests/headers/enum-doc-mod.h b/bindgen-tests/tests/headers/enum-doc-mod.h similarity index 100% rename from tests/headers/enum-doc-mod.h rename to bindgen-tests/tests/headers/enum-doc-mod.h 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/tests/headers/enum-doc-rusty.h b/bindgen-tests/tests/headers/enum-doc-rusty.h similarity index 100% rename from tests/headers/enum-doc-rusty.h rename to bindgen-tests/tests/headers/enum-doc-rusty.h diff --git a/bindgen-tests/tests/headers/enum-doc.h b/bindgen-tests/tests/headers/enum-doc.h new file mode 100644 index 0000000000..7a2f425cda --- /dev/null +++ b/bindgen-tests/tests/headers/enum-doc.h @@ -0,0 +1,18 @@ +/** Document enum */ +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, + VAR_D = 3, /**< Document field with following star */ + VAR_E = 4, /*!< Document field with following exclamation */ + /** + * Document field with preceding star, with a loong long multiline + * comment. + * + * Very interesting documentation, definitely. + */ + VAR_F, +}; diff --git a/tests/headers/enum-no-debug-rust.h b/bindgen-tests/tests/headers/enum-no-debug-rust.h similarity index 100% rename from tests/headers/enum-no-debug-rust.h rename to bindgen-tests/tests/headers/enum-no-debug-rust.h diff --git a/tests/headers/enum-translate-type.hpp b/bindgen-tests/tests/headers/enum-translate-type.hpp similarity index 100% rename from tests/headers/enum-translate-type.hpp rename to bindgen-tests/tests/headers/enum-translate-type.hpp diff --git a/bindgen-tests/tests/headers/enum-typedef.h b/bindgen-tests/tests/headers/enum-typedef.h new file mode 100644 index 0000000000..f345f4de27 --- /dev/null +++ b/bindgen-tests/tests/headers/enum-typedef.h @@ -0,0 +1,18 @@ +typedef short int16_t; + +// `cbindgen` emits this C idiom as the translation of: +// +// #[repr(i16)] +// pub enum Enum { +// Variant, +// } +enum Enum { + Variant, +}; +typedef int16_t Enum; + +// C is also fine with the typedef coming before the enum. +typedef int16_t TypedefFirst; +enum TypedefFirst { + Variant2, +}; diff --git a/tests/headers/enum-undefault.h b/bindgen-tests/tests/headers/enum-undefault.h similarity index 100% rename from tests/headers/enum-undefault.h rename to bindgen-tests/tests/headers/enum-undefault.h diff --git a/tests/headers/enum-variant-replaces.h b/bindgen-tests/tests/headers/enum-variant-replaces.h similarity index 100% rename from tests/headers/enum-variant-replaces.h rename to bindgen-tests/tests/headers/enum-variant-replaces.h diff --git a/tests/headers/enum.h b/bindgen-tests/tests/headers/enum.h similarity index 100% rename from tests/headers/enum.h rename to bindgen-tests/tests/headers/enum.h diff --git a/tests/headers/enum_alias.hpp b/bindgen-tests/tests/headers/enum_alias.hpp similarity index 100% rename from tests/headers/enum_alias.hpp rename to bindgen-tests/tests/headers/enum_alias.hpp diff --git a/tests/headers/enum_and_vtable_mangling.hpp b/bindgen-tests/tests/headers/enum_and_vtable_mangling.hpp similarity index 100% rename from tests/headers/enum_and_vtable_mangling.hpp rename to bindgen-tests/tests/headers/enum_and_vtable_mangling.hpp diff --git a/tests/headers/enum_dupe.h b/bindgen-tests/tests/headers/enum_dupe.h similarity index 100% rename from tests/headers/enum_dupe.h rename to bindgen-tests/tests/headers/enum_dupe.h diff --git a/tests/headers/enum_explicit_type.hpp b/bindgen-tests/tests/headers/enum_explicit_type.hpp similarity index 100% rename from tests/headers/enum_explicit_type.hpp rename to bindgen-tests/tests/headers/enum_explicit_type.hpp diff --git a/bindgen-tests/tests/headers/enum_explicit_type_constants.hpp b/bindgen-tests/tests/headers/enum_explicit_type_constants.hpp new file mode 100644 index 0000000000..e1ecf6fa8d --- /dev/null +++ b/bindgen-tests/tests/headers/enum_explicit_type_constants.hpp @@ -0,0 +1,5 @@ +// bindgen-flags: --raw-line '#![cfg(not(target_os="windows"))]' -- -std=c++11 +// +// This test is much like enum_explicit_type, but without --rustified-enum. + +#include "enum_explicit_type.hpp" diff --git a/tests/headers/enum_in_template.hpp b/bindgen-tests/tests/headers/enum_in_template.hpp similarity index 100% rename from tests/headers/enum_in_template.hpp rename to bindgen-tests/tests/headers/enum_in_template.hpp diff --git a/tests/headers/enum_in_template_with_typedef.hpp b/bindgen-tests/tests/headers/enum_in_template_with_typedef.hpp similarity index 100% rename from tests/headers/enum_in_template_with_typedef.hpp rename to bindgen-tests/tests/headers/enum_in_template_with_typedef.hpp diff --git a/tests/headers/enum_negative.h b/bindgen-tests/tests/headers/enum_negative.h similarity index 100% rename from tests/headers/enum_negative.h rename to bindgen-tests/tests/headers/enum_negative.h diff --git a/tests/headers/enum_packed.h b/bindgen-tests/tests/headers/enum_packed.h similarity index 100% rename from tests/headers/enum_packed.h rename to bindgen-tests/tests/headers/enum_packed.h diff --git a/tests/headers/error-E0600-cannot-apply-unary-negation-to-u32.h b/bindgen-tests/tests/headers/error-E0600-cannot-apply-unary-negation-to-u32.h similarity index 100% rename from tests/headers/error-E0600-cannot-apply-unary-negation-to-u32.h rename to bindgen-tests/tests/headers/error-E0600-cannot-apply-unary-negation-to-u32.h diff --git a/tests/headers/eval-value-dependent.hpp b/bindgen-tests/tests/headers/eval-value-dependent.hpp similarity index 100% rename from tests/headers/eval-value-dependent.hpp rename to bindgen-tests/tests/headers/eval-value-dependent.hpp diff --git a/tests/headers/eval-variadic-template-parameter.hpp b/bindgen-tests/tests/headers/eval-variadic-template-parameter.hpp similarity index 100% rename from tests/headers/eval-variadic-template-parameter.hpp rename to bindgen-tests/tests/headers/eval-variadic-template-parameter.hpp diff --git a/tests/headers/explicit-padding.h b/bindgen-tests/tests/headers/explicit-padding.h similarity index 100% rename from tests/headers/explicit-padding.h rename to bindgen-tests/tests/headers/explicit-padding.h diff --git a/bindgen-tests/tests/headers/extern-const-struct.h b/bindgen-tests/tests/headers/extern-const-struct.h new file mode 100644 index 0000000000..10006e8284 --- /dev/null +++ b/bindgen-tests/tests/headers/extern-const-struct.h @@ -0,0 +1,5 @@ +struct nsFoo { + float details[400]; +}; + +extern const struct nsFoo gDetails; 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/tests/headers/extern.hpp b/bindgen-tests/tests/headers/extern.hpp similarity index 100% rename from tests/headers/extern.hpp rename to bindgen-tests/tests/headers/extern.hpp 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/field-visibility-callback.h b/bindgen-tests/tests/headers/field-visibility-callback.h new file mode 100644 index 0000000000..d2fe3ace80 --- /dev/null +++ b/bindgen-tests/tests/headers/field-visibility-callback.h @@ -0,0 +1,9 @@ +// bindgen-flags: --default-visibility private +// bindgen-parse-callbacks: field-visibility-default-private + +struct my_struct { + int a; + int private_b; + int c: 1; + int private_d: 1; +}; diff --git a/bindgen-tests/tests/headers/field-visibility.h b/bindgen-tests/tests/headers/field-visibility.h new file mode 100644 index 0000000000..adb73159c2 --- /dev/null +++ b/bindgen-tests/tests/headers/field-visibility.h @@ -0,0 +1,10 @@ +// bindgen-flags: --default-visibility private --no-doc-comments + +struct my_struct1 { + int a: 1; +}; + +/**
*/ +struct my_struct2 { + int a: 1; +}; diff --git a/tests/headers/fit-macro-constant-types-signed.h b/bindgen-tests/tests/headers/fit-macro-constant-types-signed.h similarity index 100% rename from tests/headers/fit-macro-constant-types-signed.h rename to bindgen-tests/tests/headers/fit-macro-constant-types-signed.h diff --git a/tests/headers/fit-macro-constant-types.h b/bindgen-tests/tests/headers/fit-macro-constant-types.h similarity index 100% rename from tests/headers/fit-macro-constant-types.h rename to bindgen-tests/tests/headers/fit-macro-constant-types.h diff --git a/bindgen-tests/tests/headers/flexarray.hpp b/bindgen-tests/tests/headers/flexarray.hpp new file mode 100644 index 0000000000..b698c38d19 --- /dev/null +++ b/bindgen-tests/tests/headers/flexarray.hpp @@ -0,0 +1,32 @@ +// bindgen-flags: --rust-target nightly --flexarray-dst --raw-line '#![cfg(feature = "nightly")]' --raw-line '#![feature(ptr_metadata, layout_for_ptr)]' + +struct flexarray { + int count; + int data[]; +}; + +struct flexarray_zero { + int count; + int data[0]; +}; + +template +struct flexarray_template { + int count; + T data[]; +}; + +struct flexarray_ref { + flexarray *things; +}; + +struct flexarray_bogus_zero_fam { + int count; + int data1[0]; + char data2[]; +}; + +struct flexarray_align { + int count; + int data[]; +} __attribute__((aligned(128))); diff --git a/tests/headers/float128.hpp b/bindgen-tests/tests/headers/float128.hpp similarity index 100% rename from tests/headers/float128.hpp rename to bindgen-tests/tests/headers/float128.hpp diff --git a/bindgen-tests/tests/headers/float16.h b/bindgen-tests/tests/headers/float16.h new file mode 100644 index 0000000000..3b1058591d --- /dev/null +++ b/bindgen-tests/tests/headers/float16.h @@ -0,0 +1,36 @@ +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq + +static __fp16 global; + +struct Test__Float16 +{ + __fp16 f; +}; + +struct Test__Float16Ref +{ + __fp16 *f; +}; + +/* +// This options are currently supported only on specific targets (eg. x86 with sse2) +_Float16 returns_f16(); + +void gets_f16(_Float16 arg); + +struct Test__Float16_Complex +{ + _Float16 _Complex mMember; +}; + +struct Test__Float16_ComplexPtr +{ + _Float16 _Complex *mMember; +}; + +_Float16 _Complex globalValueHalf; + +_Float16 _Complex returns_f16_complex(); + +void gets_f16_complex(_Float16 _Complex arg); +*/ \ No newline at end of file diff --git a/tests/headers/forward-declaration-autoptr.hpp b/bindgen-tests/tests/headers/forward-declaration-autoptr.hpp similarity index 100% rename from tests/headers/forward-declaration-autoptr.hpp rename to bindgen-tests/tests/headers/forward-declaration-autoptr.hpp diff --git a/tests/headers/forward-enum-decl.hpp b/bindgen-tests/tests/headers/forward-enum-decl.hpp similarity index 100% rename from tests/headers/forward-enum-decl.hpp rename to bindgen-tests/tests/headers/forward-enum-decl.hpp diff --git a/tests/headers/forward-inherit-struct-with-fields.hpp b/bindgen-tests/tests/headers/forward-inherit-struct-with-fields.hpp similarity index 100% rename from tests/headers/forward-inherit-struct-with-fields.hpp rename to bindgen-tests/tests/headers/forward-inherit-struct-with-fields.hpp diff --git a/tests/headers/forward-inherit-struct.hpp b/bindgen-tests/tests/headers/forward-inherit-struct.hpp similarity index 100% rename from tests/headers/forward-inherit-struct.hpp rename to bindgen-tests/tests/headers/forward-inherit-struct.hpp diff --git a/tests/headers/forward_declared_complex_types.hpp b/bindgen-tests/tests/headers/forward_declared_complex_types.hpp similarity index 100% rename from tests/headers/forward_declared_complex_types.hpp rename to bindgen-tests/tests/headers/forward_declared_complex_types.hpp diff --git a/bindgen-tests/tests/headers/forward_declared_opaque.h b/bindgen-tests/tests/headers/forward_declared_opaque.h new file mode 100644 index 0000000000..69a12cc7e2 --- /dev/null +++ b/bindgen-tests/tests/headers/forward_declared_opaque.h @@ -0,0 +1,4 @@ +// bindgen-flags: --opaque-type ".*" + +union a; +struct b; diff --git a/tests/headers/forward_declared_struct.h b/bindgen-tests/tests/headers/forward_declared_struct.h similarity index 100% rename from tests/headers/forward_declared_struct.h rename to bindgen-tests/tests/headers/forward_declared_struct.h diff --git a/tests/headers/func_proto.h b/bindgen-tests/tests/headers/func_proto.h similarity index 100% rename from tests/headers/func_proto.h rename to bindgen-tests/tests/headers/func_proto.h diff --git a/tests/headers/func_ptr.h b/bindgen-tests/tests/headers/func_ptr.h similarity index 100% rename from tests/headers/func_ptr.h rename to bindgen-tests/tests/headers/func_ptr.h diff --git a/tests/headers/func_ptr_in_struct.h b/bindgen-tests/tests/headers/func_ptr_in_struct.h similarity index 100% rename from tests/headers/func_ptr_in_struct.h rename to bindgen-tests/tests/headers/func_ptr_in_struct.h diff --git a/tests/headers/func_ptr_return_type.h b/bindgen-tests/tests/headers/func_ptr_return_type.h similarity index 100% rename from tests/headers/func_ptr_return_type.h rename to bindgen-tests/tests/headers/func_ptr_return_type.h diff --git a/bindgen-tests/tests/headers/func_return_must_use.h b/bindgen-tests/tests/headers/func_return_must_use.h new file mode 100644 index 0000000000..f05bd2de40 --- /dev/null +++ b/bindgen-tests/tests/headers/func_return_must_use.h @@ -0,0 +1,36 @@ +// bindgen-flags: --must-use-type 'MustUse.*' + +typedef int MustUseInt; + +MustUseInt return_int(); + +struct MustUseStruct; + +struct MustUseStruct return_struct(); + +/** + *
+ */ +typedef int AnnotatedInt; + +AnnotatedInt return_annotated_int(); + +int return_plain_int(); + +/** + *
+ */ +struct AnnotatedStruct {}; + +struct AnnotatedStruct return_annotated_struct(); + +struct PlainStruct {}; + +/** + *
+ */ +typedef struct PlainStruct TypedefPlainStruct; + +struct PlainStruct return_plain_struct(); + +TypedefPlainStruct return_typedef_struct(); diff --git a/tests/headers/func_with_array_arg.h b/bindgen-tests/tests/headers/func_with_array_arg.h similarity index 100% rename from tests/headers/func_with_array_arg.h rename to bindgen-tests/tests/headers/func_with_array_arg.h diff --git a/tests/headers/func_with_func_ptr_arg.h b/bindgen-tests/tests/headers/func_with_func_ptr_arg.h similarity index 100% rename from tests/headers/func_with_func_ptr_arg.h rename to bindgen-tests/tests/headers/func_with_func_ptr_arg.h diff --git a/tests/headers/function-typedef-stdcall.h b/bindgen-tests/tests/headers/function-typedef-stdcall.h similarity index 100% rename from tests/headers/function-typedef-stdcall.h rename to bindgen-tests/tests/headers/function-typedef-stdcall.h diff --git a/tests/headers/gen-constructors-neg.hpp b/bindgen-tests/tests/headers/gen-constructors-neg.hpp similarity index 100% rename from tests/headers/gen-constructors-neg.hpp rename to bindgen-tests/tests/headers/gen-constructors-neg.hpp diff --git a/tests/headers/gen-constructors.hpp b/bindgen-tests/tests/headers/gen-constructors.hpp similarity index 100% rename from tests/headers/gen-constructors.hpp rename to bindgen-tests/tests/headers/gen-constructors.hpp diff --git a/tests/headers/gen-destructors-neg.hpp b/bindgen-tests/tests/headers/gen-destructors-neg.hpp similarity index 100% rename from tests/headers/gen-destructors-neg.hpp rename to bindgen-tests/tests/headers/gen-destructors-neg.hpp diff --git a/tests/headers/gen-destructors.hpp b/bindgen-tests/tests/headers/gen-destructors.hpp similarity index 100% rename from tests/headers/gen-destructors.hpp rename to bindgen-tests/tests/headers/gen-destructors.hpp diff --git a/tests/headers/generate-inline.hpp b/bindgen-tests/tests/headers/generate-inline.hpp similarity index 100% rename from tests/headers/generate-inline.hpp rename to bindgen-tests/tests/headers/generate-inline.hpp diff --git a/bindgen-tests/tests/headers/i128.h b/bindgen-tests/tests/headers/i128.h new file mode 100644 index 0000000000..1880f11305 --- /dev/null +++ b/bindgen-tests/tests/headers/i128.h @@ -0,0 +1,4 @@ +struct foo { + __int128 my_signed; + unsigned __int128 my_unsigned; +}; diff --git a/tests/headers/in_class_typedef.hpp b/bindgen-tests/tests/headers/in_class_typedef.hpp similarity index 100% rename from tests/headers/in_class_typedef.hpp rename to bindgen-tests/tests/headers/in_class_typedef.hpp diff --git a/tests/headers/incomplete-array-padding.h b/bindgen-tests/tests/headers/incomplete-array-padding.h similarity index 100% rename from tests/headers/incomplete-array-padding.h rename to bindgen-tests/tests/headers/incomplete-array-padding.h 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/tests/headers/inherit-from-template-instantiation-with-vtable.hpp b/bindgen-tests/tests/headers/inherit-from-template-instantiation-with-vtable.hpp similarity index 100% rename from tests/headers/inherit-from-template-instantiation-with-vtable.hpp rename to bindgen-tests/tests/headers/inherit-from-template-instantiation-with-vtable.hpp diff --git a/tests/headers/inherit-namespaced.hpp b/bindgen-tests/tests/headers/inherit-namespaced.hpp similarity index 100% rename from tests/headers/inherit-namespaced.hpp rename to bindgen-tests/tests/headers/inherit-namespaced.hpp diff --git a/bindgen-tests/tests/headers/inherit_multiple_interfaces.hpp b/bindgen-tests/tests/headers/inherit_multiple_interfaces.hpp new file mode 100644 index 0000000000..725992c7cd --- /dev/null +++ b/bindgen-tests/tests/headers/inherit_multiple_interfaces.hpp @@ -0,0 +1,15 @@ +class A { + virtual void Foo(); + + int member; +}; + +class B { + virtual void Bar(); + + void* member2; +}; + +class C : public A, public B { + float member3; +}; diff --git a/tests/headers/inherit_named.hpp b/bindgen-tests/tests/headers/inherit_named.hpp similarity index 100% rename from tests/headers/inherit_named.hpp rename to bindgen-tests/tests/headers/inherit_named.hpp diff --git a/tests/headers/inherit_typedef.hpp b/bindgen-tests/tests/headers/inherit_typedef.hpp similarity index 100% rename from tests/headers/inherit_typedef.hpp rename to bindgen-tests/tests/headers/inherit_typedef.hpp diff --git a/tests/headers/inline-function.h b/bindgen-tests/tests/headers/inline-function.h similarity index 100% rename from tests/headers/inline-function.h rename to bindgen-tests/tests/headers/inline-function.h diff --git a/tests/headers/inline_namespace.hpp b/bindgen-tests/tests/headers/inline_namespace.hpp similarity index 100% rename from tests/headers/inline_namespace.hpp rename to bindgen-tests/tests/headers/inline_namespace.hpp diff --git a/tests/headers/inline_namespace_allowlist.hpp b/bindgen-tests/tests/headers/inline_namespace_allowlist.hpp similarity index 100% rename from tests/headers/inline_namespace_allowlist.hpp rename to bindgen-tests/tests/headers/inline_namespace_allowlist.hpp diff --git a/tests/headers/inline_namespace_conservative.hpp b/bindgen-tests/tests/headers/inline_namespace_conservative.hpp similarity index 100% rename from tests/headers/inline_namespace_conservative.hpp rename to bindgen-tests/tests/headers/inline_namespace_conservative.hpp 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/inline_namespace_nested.hpp b/bindgen-tests/tests/headers/inline_namespace_nested.hpp new file mode 100644 index 0000000000..5c542e195c --- /dev/null +++ b/bindgen-tests/tests/headers/inline_namespace_nested.hpp @@ -0,0 +1,5 @@ +// bindgen-flags: --enable-cxx-namespaces -- -std=c++2a + +namespace ranges::inline foo::bar { + static int bar = 0; +} diff --git a/tests/headers/inline_namespace_no_ns_enabled.hpp b/bindgen-tests/tests/headers/inline_namespace_no_ns_enabled.hpp similarity index 100% rename from tests/headers/inline_namespace_no_ns_enabled.hpp rename to bindgen-tests/tests/headers/inline_namespace_no_ns_enabled.hpp diff --git a/bindgen-tests/tests/headers/inner-typedef-gh422.hpp b/bindgen-tests/tests/headers/inner-typedef-gh422.hpp new file mode 100644 index 0000000000..301630a5e0 --- /dev/null +++ b/bindgen-tests/tests/headers/inner-typedef-gh422.hpp @@ -0,0 +1,11 @@ +template +class Foo { +public: + class InnerType { + T t; + }; +}; + +typedef Foo::InnerType Bar; + +Bar func(); \ No newline at end of file diff --git a/tests/headers/inner_const.hpp b/bindgen-tests/tests/headers/inner_const.hpp similarity index 100% rename from tests/headers/inner_const.hpp rename to bindgen-tests/tests/headers/inner_const.hpp diff --git a/tests/headers/inner_template_self.hpp b/bindgen-tests/tests/headers/inner_template_self.hpp similarity index 100% rename from tests/headers/inner_template_self.hpp rename to bindgen-tests/tests/headers/inner_template_self.hpp diff --git a/tests/headers/int128_t.h b/bindgen-tests/tests/headers/int128_t.h similarity index 100% rename from tests/headers/int128_t.h rename to bindgen-tests/tests/headers/int128_t.h diff --git a/tests/headers/issue-1025-unknown-enum-repr.hpp b/bindgen-tests/tests/headers/issue-1025-unknown-enum-repr.hpp similarity index 100% rename from tests/headers/issue-1025-unknown-enum-repr.hpp rename to bindgen-tests/tests/headers/issue-1025-unknown-enum-repr.hpp diff --git a/tests/headers/issue-1034.h b/bindgen-tests/tests/headers/issue-1034.h similarity index 100% rename from tests/headers/issue-1034.h rename to bindgen-tests/tests/headers/issue-1034.h diff --git a/tests/headers/issue-1040.h b/bindgen-tests/tests/headers/issue-1040.h similarity index 100% rename from tests/headers/issue-1040.h rename to bindgen-tests/tests/headers/issue-1040.h diff --git a/tests/headers/issue-1076-unnamed-bitfield-alignment.h b/bindgen-tests/tests/headers/issue-1076-unnamed-bitfield-alignment.h similarity index 100% rename from tests/headers/issue-1076-unnamed-bitfield-alignment.h rename to bindgen-tests/tests/headers/issue-1076-unnamed-bitfield-alignment.h diff --git a/tests/headers/issue-1113-template-references.hpp b/bindgen-tests/tests/headers/issue-1113-template-references.hpp similarity index 100% rename from tests/headers/issue-1113-template-references.hpp rename to bindgen-tests/tests/headers/issue-1113-template-references.hpp diff --git a/tests/headers/issue-1118-using-forward-decl.hpp b/bindgen-tests/tests/headers/issue-1118-using-forward-decl.hpp similarity index 100% rename from tests/headers/issue-1118-using-forward-decl.hpp rename to bindgen-tests/tests/headers/issue-1118-using-forward-decl.hpp diff --git a/tests/headers/issue-1197-pure-virtual-stuff.hpp b/bindgen-tests/tests/headers/issue-1197-pure-virtual-stuff.hpp similarity index 100% rename from tests/headers/issue-1197-pure-virtual-stuff.hpp rename to bindgen-tests/tests/headers/issue-1197-pure-virtual-stuff.hpp diff --git a/tests/headers/issue-1198-alias-rust-bitfield-enum.h b/bindgen-tests/tests/headers/issue-1198-alias-rust-bitfield-enum.h similarity index 100% rename from tests/headers/issue-1198-alias-rust-bitfield-enum.h rename to bindgen-tests/tests/headers/issue-1198-alias-rust-bitfield-enum.h diff --git a/tests/headers/issue-1198-alias-rust-const-mod-bitfield-enum.h b/bindgen-tests/tests/headers/issue-1198-alias-rust-const-mod-bitfield-enum.h similarity index 100% rename from tests/headers/issue-1198-alias-rust-const-mod-bitfield-enum.h rename to bindgen-tests/tests/headers/issue-1198-alias-rust-const-mod-bitfield-enum.h diff --git a/tests/headers/issue-1198-alias-rust-const-mod-enum.h b/bindgen-tests/tests/headers/issue-1198-alias-rust-const-mod-enum.h similarity index 100% rename from tests/headers/issue-1198-alias-rust-const-mod-enum.h rename to bindgen-tests/tests/headers/issue-1198-alias-rust-const-mod-enum.h diff --git a/tests/headers/issue-1198-alias-rust-enum.h b/bindgen-tests/tests/headers/issue-1198-alias-rust-enum.h similarity index 100% rename from tests/headers/issue-1198-alias-rust-enum.h rename to bindgen-tests/tests/headers/issue-1198-alias-rust-enum.h diff --git a/tests/headers/issue-1216-variadic-member.h b/bindgen-tests/tests/headers/issue-1216-variadic-member.h similarity index 100% rename from tests/headers/issue-1216-variadic-member.h rename to bindgen-tests/tests/headers/issue-1216-variadic-member.h diff --git a/tests/headers/issue-1238-fwd-no-copy.h b/bindgen-tests/tests/headers/issue-1238-fwd-no-copy.h similarity index 100% rename from tests/headers/issue-1238-fwd-no-copy.h rename to bindgen-tests/tests/headers/issue-1238-fwd-no-copy.h diff --git a/tests/headers/issue-1281.h b/bindgen-tests/tests/headers/issue-1281.h similarity index 100% rename from tests/headers/issue-1281.h rename to bindgen-tests/tests/headers/issue-1281.h diff --git a/tests/headers/issue-1285.h b/bindgen-tests/tests/headers/issue-1285.h similarity index 100% rename from tests/headers/issue-1285.h rename to bindgen-tests/tests/headers/issue-1285.h diff --git a/tests/headers/issue-1291.hpp b/bindgen-tests/tests/headers/issue-1291.hpp similarity index 89% rename from tests/headers/issue-1291.hpp rename to bindgen-tests/tests/headers/issue-1291.hpp index 4ec524f12f..cb4aeb91f8 100644 --- a/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/tests/headers/issue-1350-attribute-overloadable.h b/bindgen-tests/tests/headers/issue-1350-attribute-overloadable.h similarity index 100% rename from tests/headers/issue-1350-attribute-overloadable.h rename to bindgen-tests/tests/headers/issue-1350-attribute-overloadable.h diff --git a/bindgen-tests/tests/headers/issue-1375-prefixed-functions.h b/bindgen-tests/tests/headers/issue-1375-prefixed-functions.h new file mode 100644 index 0000000000..cc37c8ad80 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-1375-prefixed-functions.h @@ -0,0 +1,8 @@ +// bindgen-parse-callbacks: remove-function-prefix-my_custom_prefix_ + +extern const int my_custom_prefix_var_const_name; + +extern int my_custom_prefix_var_mut_name; + +void my_custom_prefix_function_name(const int x); + diff --git a/tests/headers/issue-1382-rust-primitive-types.h b/bindgen-tests/tests/headers/issue-1382-rust-primitive-types.h similarity index 100% rename from tests/headers/issue-1382-rust-primitive-types.h rename to bindgen-tests/tests/headers/issue-1382-rust-primitive-types.h diff --git a/tests/headers/issue-1435.hpp b/bindgen-tests/tests/headers/issue-1435.hpp similarity index 100% rename from tests/headers/issue-1435.hpp rename to bindgen-tests/tests/headers/issue-1435.hpp diff --git a/tests/headers/issue-1443.hpp b/bindgen-tests/tests/headers/issue-1443.hpp similarity index 100% rename from tests/headers/issue-1443.hpp rename to bindgen-tests/tests/headers/issue-1443.hpp diff --git a/tests/headers/issue-1454.h b/bindgen-tests/tests/headers/issue-1454.h similarity index 100% rename from tests/headers/issue-1454.h rename to bindgen-tests/tests/headers/issue-1454.h diff --git a/tests/headers/issue-1464.hpp b/bindgen-tests/tests/headers/issue-1464.hpp similarity index 100% rename from tests/headers/issue-1464.hpp rename to bindgen-tests/tests/headers/issue-1464.hpp diff --git a/tests/headers/issue-1488-enum-new-type.h b/bindgen-tests/tests/headers/issue-1488-enum-new-type.h similarity index 100% rename from tests/headers/issue-1488-enum-new-type.h rename to bindgen-tests/tests/headers/issue-1488-enum-new-type.h diff --git a/tests/headers/issue-1488-options.h b/bindgen-tests/tests/headers/issue-1488-options.h similarity index 100% rename from tests/headers/issue-1488-options.h rename to bindgen-tests/tests/headers/issue-1488-options.h diff --git a/tests/headers/issue-1488-template-alias-new-type.hpp b/bindgen-tests/tests/headers/issue-1488-template-alias-new-type.hpp similarity index 100% rename from tests/headers/issue-1488-template-alias-new-type.hpp rename to bindgen-tests/tests/headers/issue-1488-template-alias-new-type.hpp diff --git a/tests/headers/issue-1498.h b/bindgen-tests/tests/headers/issue-1498.h similarity index 100% rename from tests/headers/issue-1498.h rename to bindgen-tests/tests/headers/issue-1498.h diff --git a/tests/headers/issue-1514.hpp b/bindgen-tests/tests/headers/issue-1514.hpp similarity index 100% rename from tests/headers/issue-1514.hpp rename to bindgen-tests/tests/headers/issue-1514.hpp diff --git a/tests/headers/issue-1554.h b/bindgen-tests/tests/headers/issue-1554.h similarity index 100% rename from tests/headers/issue-1554.h rename to bindgen-tests/tests/headers/issue-1554.h diff --git a/tests/headers/issue-1599-opaque-typedef-to-enum.h b/bindgen-tests/tests/headers/issue-1599-opaque-typedef-to-enum.h similarity index 100% rename from tests/headers/issue-1599-opaque-typedef-to-enum.h rename to bindgen-tests/tests/headers/issue-1599-opaque-typedef-to-enum.h diff --git a/tests/headers/issue-1676-macro-namespace-prefix.hpp b/bindgen-tests/tests/headers/issue-1676-macro-namespace-prefix.hpp similarity index 100% rename from tests/headers/issue-1676-macro-namespace-prefix.hpp rename to bindgen-tests/tests/headers/issue-1676-macro-namespace-prefix.hpp diff --git a/tests/headers/issue-1947.h b/bindgen-tests/tests/headers/issue-1947.h similarity index 100% rename from tests/headers/issue-1947.h rename to bindgen-tests/tests/headers/issue-1947.h diff --git a/tests/headers/issue-1977-larger-arrays.hpp b/bindgen-tests/tests/headers/issue-1977-larger-arrays.hpp similarity index 100% rename from tests/headers/issue-1977-larger-arrays.hpp rename to bindgen-tests/tests/headers/issue-1977-larger-arrays.hpp diff --git a/tests/headers/issue-1995.h b/bindgen-tests/tests/headers/issue-1995.h similarity index 100% rename from tests/headers/issue-1995.h rename to bindgen-tests/tests/headers/issue-1995.h diff --git a/tests/headers/issue-2019.hpp b/bindgen-tests/tests/headers/issue-2019.hpp similarity index 100% rename from tests/headers/issue-2019.hpp rename to bindgen-tests/tests/headers/issue-2019.hpp diff --git a/bindgen-tests/tests/headers/issue-2239-template-dependent-bit-width.hpp b/bindgen-tests/tests/headers/issue-2239-template-dependent-bit-width.hpp new file mode 100644 index 0000000000..4e6feb3f1e --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2239-template-dependent-bit-width.hpp @@ -0,0 +1,10 @@ +template class b { + typedef a td; + using ta = a; + struct foo { + a foo : sizeof(a); + a : sizeof(a); + td : sizeof(td); + ta : sizeof(ta); + }; +}; diff --git a/bindgen-tests/tests/headers/issue-2556.h b/bindgen-tests/tests/headers/issue-2556.h new file mode 100644 index 0000000000..bbb1b874ec --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2556.h @@ -0,0 +1,4 @@ +// bindgen-flags: --enable-cxx-namespaces -- -x c++ -Itests/headers -include tests/headers/issue-2556/nsStyleStruct.h -include tests/headers/issue-2556/LayoutConstants.h + +#include "issue-2556/nsSize.h" +#include "issue-2556/nsStyleStruct.h" diff --git a/bindgen-tests/tests/headers/issue-2556/LayoutConstants.h b/bindgen-tests/tests/headers/issue-2556/LayoutConstants.h new file mode 100644 index 0000000000..2ed1c864b2 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2556/LayoutConstants.h @@ -0,0 +1,7 @@ +#include "nsSize.h" + +namespace foo { + +static constexpr nsSize kFallbackIntrinsicSize(0, 0); + +} diff --git a/bindgen-tests/tests/headers/issue-2556/nsSize.h b/bindgen-tests/tests/headers/issue-2556/nsSize.h new file mode 100644 index 0000000000..8fe8b95023 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2556/nsSize.h @@ -0,0 +1,6 @@ +#pragma once + +struct nsSize { + int width, height; + constexpr nsSize(int aWidth, int aHeight) : width(aWidth), height(aHeight) {} +}; diff --git a/bindgen-tests/tests/headers/issue-2556/nsStyleStruct.h b/bindgen-tests/tests/headers/issue-2556/nsStyleStruct.h new file mode 100644 index 0000000000..4c6eedfb9a --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2556/nsStyleStruct.h @@ -0,0 +1,3 @@ +#pragma once + +#include "nsSize.h" diff --git a/bindgen-tests/tests/headers/issue-2566-cstr.h b/bindgen-tests/tests/headers/issue-2566-cstr.h new file mode 100644 index 0000000000..674b894024 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2566-cstr.h @@ -0,0 +1,4 @@ +// bindgen-flags: --generate-cstr + +/// We should _not_ generate a cstr for this because cstr shouldn't have interior nulls. +#define FOO "a\0b" diff --git a/bindgen-tests/tests/headers/issue-2566.h b/bindgen-tests/tests/headers/issue-2566.h new file mode 100644 index 0000000000..6e15ec1979 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2566.h @@ -0,0 +1 @@ +#define FOO "a\0b" 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-2695.h b/bindgen-tests/tests/headers/issue-2695.h new file mode 100644 index 0000000000..4fbcc39bf8 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2695.h @@ -0,0 +1,10 @@ +// bindgen-flags: --explicit-padding + +#pragma pack(2) + +struct Test { + unsigned long x; + char a; + char b; + char c; +}; 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/tests/headers/issue-358.hpp b/bindgen-tests/tests/headers/issue-358.hpp similarity index 100% rename from tests/headers/issue-358.hpp rename to bindgen-tests/tests/headers/issue-358.hpp diff --git a/bindgen-tests/tests/headers/issue-372.hpp b/bindgen-tests/tests/headers/issue-372.hpp new file mode 100644 index 0000000000..7127be2ccb --- /dev/null +++ b/bindgen-tests/tests/headers/issue-372.hpp @@ -0,0 +1,16 @@ +// bindgen-flags: --enable-cxx-namespaces --rustified-enum ".*" +template class c { a e[b]; }; +class d; +template class C { c h; }; +class i { + i *j; + i *k; + bool l; +}; +class d { + i m; +}; +enum n { o, p, q, r, s, t, b, ae, e, ag, ah, ai }; +class F { + C w; +}; diff --git a/tests/headers/issue-410.hpp b/bindgen-tests/tests/headers/issue-410.hpp similarity index 100% rename from tests/headers/issue-410.hpp rename to bindgen-tests/tests/headers/issue-410.hpp diff --git a/tests/headers/issue-446.hpp b/bindgen-tests/tests/headers/issue-446.hpp similarity index 100% rename from tests/headers/issue-446.hpp rename to bindgen-tests/tests/headers/issue-446.hpp diff --git a/tests/headers/issue-447.hpp b/bindgen-tests/tests/headers/issue-447.hpp similarity index 100% rename from tests/headers/issue-447.hpp rename to bindgen-tests/tests/headers/issue-447.hpp diff --git a/tests/headers/issue-493.hpp b/bindgen-tests/tests/headers/issue-493.hpp similarity index 100% rename from tests/headers/issue-493.hpp rename to bindgen-tests/tests/headers/issue-493.hpp diff --git a/tests/headers/issue-511.h b/bindgen-tests/tests/headers/issue-511.h similarity index 100% rename from tests/headers/issue-511.h rename to bindgen-tests/tests/headers/issue-511.h diff --git a/bindgen-tests/tests/headers/issue-537-repr-packed-n.h b/bindgen-tests/tests/headers/issue-537-repr-packed-n.h new file mode 100644 index 0000000000..40be004c85 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-537-repr-packed-n.h @@ -0,0 +1,34 @@ +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' + +/// This should not be opaque; we can see the attributes and can pack the +/// struct. +struct AlignedToOne { + int i; +} __attribute__ ((packed,aligned(1))); + +/// This should be packed because Rust 1.33 has `#[repr(packed(N))]`. +struct AlignedToTwo { + int i; +} __attribute__ ((packed,aligned(2))); + +#pragma pack(1) + +/// 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. +struct PackedToOne { + int x; + int y; +}; + +#pragma pack() + +#pragma pack(2) + +/// This should be packed because Rust 1.33 has `#[repr(packed(N))]`. +struct PackedToTwo { + int x; + int y; +}; + +#pragma pack() diff --git a/tests/headers/issue-537.h b/bindgen-tests/tests/headers/issue-537.h similarity index 100% rename from tests/headers/issue-537.h rename to bindgen-tests/tests/headers/issue-537.h diff --git a/bindgen-tests/tests/headers/issue-544-stylo-creduce-2.hpp b/bindgen-tests/tests/headers/issue-544-stylo-creduce-2.hpp new file mode 100644 index 0000000000..b41b422d1e --- /dev/null +++ b/bindgen-tests/tests/headers/issue-544-stylo-creduce-2.hpp @@ -0,0 +1,15 @@ +// bindgen-flags: -- -std=c++14 + +template +struct Foo { + template using FirstAlias = typename T::Associated; + template using SecondAlias = Foo>; + +#if 0 + // FIXME: This regressed sometime between libclang 9 and 16, though it + // never quite worked properly so... + SecondAlias member; +#else + SecondAlias* member; +#endif +}; diff --git a/tests/headers/issue-544-stylo-creduce.hpp b/bindgen-tests/tests/headers/issue-544-stylo-creduce.hpp similarity index 100% rename from tests/headers/issue-544-stylo-creduce.hpp rename to bindgen-tests/tests/headers/issue-544-stylo-creduce.hpp diff --git a/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp b/bindgen-tests/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp similarity index 100% rename from tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp rename to bindgen-tests/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp diff --git a/tests/headers/issue-573-layout-test-failures.hpp b/bindgen-tests/tests/headers/issue-573-layout-test-failures.hpp similarity index 100% rename from tests/headers/issue-573-layout-test-failures.hpp rename to bindgen-tests/tests/headers/issue-573-layout-test-failures.hpp diff --git a/tests/headers/issue-574-assertion-failure-in-codegen.hpp b/bindgen-tests/tests/headers/issue-574-assertion-failure-in-codegen.hpp similarity index 100% rename from tests/headers/issue-574-assertion-failure-in-codegen.hpp rename to bindgen-tests/tests/headers/issue-574-assertion-failure-in-codegen.hpp diff --git a/tests/headers/issue-584-stylo-template-analysis-panic.hpp b/bindgen-tests/tests/headers/issue-584-stylo-template-analysis-panic.hpp similarity index 100% rename from tests/headers/issue-584-stylo-template-analysis-panic.hpp rename to bindgen-tests/tests/headers/issue-584-stylo-template-analysis-panic.hpp diff --git a/tests/headers/issue-638-stylo-cannot-find-T-in-this-scope.hpp b/bindgen-tests/tests/headers/issue-638-stylo-cannot-find-T-in-this-scope.hpp similarity index 100% rename from tests/headers/issue-638-stylo-cannot-find-T-in-this-scope.hpp rename to bindgen-tests/tests/headers/issue-638-stylo-cannot-find-T-in-this-scope.hpp diff --git a/tests/headers/issue-639-typedef-anon-field.hpp b/bindgen-tests/tests/headers/issue-639-typedef-anon-field.hpp similarity index 100% rename from tests/headers/issue-639-typedef-anon-field.hpp rename to bindgen-tests/tests/headers/issue-639-typedef-anon-field.hpp diff --git a/tests/headers/issue-643-inner-struct.h b/bindgen-tests/tests/headers/issue-643-inner-struct.h similarity index 100% rename from tests/headers/issue-643-inner-struct.h rename to bindgen-tests/tests/headers/issue-643-inner-struct.h diff --git a/tests/headers/issue-645-cannot-find-type-T-in-this-scope.hpp b/bindgen-tests/tests/headers/issue-645-cannot-find-type-T-in-this-scope.hpp similarity index 100% rename from tests/headers/issue-645-cannot-find-type-T-in-this-scope.hpp rename to bindgen-tests/tests/headers/issue-645-cannot-find-type-T-in-this-scope.hpp diff --git a/tests/headers/issue-648-derive-debug-with-padding.h b/bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h similarity index 93% rename from tests/headers/issue-648-derive-debug-with-padding.h rename to bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h index 0860ce9502..d54fe374ce 100644 --- a/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/tests/headers/issue-654-struct-fn-collision.h b/bindgen-tests/tests/headers/issue-654-struct-fn-collision.h similarity index 100% rename from tests/headers/issue-654-struct-fn-collision.h rename to bindgen-tests/tests/headers/issue-654-struct-fn-collision.h diff --git a/tests/headers/issue-662-cannot-find-T-in-this-scope.hpp b/bindgen-tests/tests/headers/issue-662-cannot-find-T-in-this-scope.hpp similarity index 100% rename from tests/headers/issue-662-cannot-find-T-in-this-scope.hpp rename to bindgen-tests/tests/headers/issue-662-cannot-find-T-in-this-scope.hpp diff --git a/tests/headers/issue-662-part-2.hpp b/bindgen-tests/tests/headers/issue-662-part-2.hpp similarity index 100% rename from tests/headers/issue-662-part-2.hpp rename to bindgen-tests/tests/headers/issue-662-part-2.hpp diff --git a/tests/headers/issue-674-1.hpp b/bindgen-tests/tests/headers/issue-674-1.hpp similarity index 100% rename from tests/headers/issue-674-1.hpp rename to bindgen-tests/tests/headers/issue-674-1.hpp diff --git a/tests/headers/issue-674-2.hpp b/bindgen-tests/tests/headers/issue-674-2.hpp similarity index 100% rename from tests/headers/issue-674-2.hpp rename to bindgen-tests/tests/headers/issue-674-2.hpp diff --git a/tests/headers/issue-674-3.hpp b/bindgen-tests/tests/headers/issue-674-3.hpp similarity index 100% rename from tests/headers/issue-674-3.hpp rename to bindgen-tests/tests/headers/issue-674-3.hpp diff --git a/tests/headers/issue-677-nested-ns-specifier.hpp b/bindgen-tests/tests/headers/issue-677-nested-ns-specifier.hpp similarity index 100% rename from tests/headers/issue-677-nested-ns-specifier.hpp rename to bindgen-tests/tests/headers/issue-677-nested-ns-specifier.hpp diff --git a/tests/headers/issue-691-template-parameter-virtual.hpp b/bindgen-tests/tests/headers/issue-691-template-parameter-virtual.hpp similarity index 100% rename from tests/headers/issue-691-template-parameter-virtual.hpp rename to bindgen-tests/tests/headers/issue-691-template-parameter-virtual.hpp diff --git a/tests/headers/issue-710-must-use-type.h b/bindgen-tests/tests/headers/issue-710-must-use-type.h similarity index 100% rename from tests/headers/issue-710-must-use-type.h rename to bindgen-tests/tests/headers/issue-710-must-use-type.h diff --git a/tests/headers/issue-739-pointer-wide-bitfield.h b/bindgen-tests/tests/headers/issue-739-pointer-wide-bitfield.h similarity index 75% rename from tests/headers/issue-739-pointer-wide-bitfield.h rename to bindgen-tests/tests/headers/issue-739-pointer-wide-bitfield.h index 611dab1da0..eeb7ae9c2d 100644 --- a/tests/headers/issue-739-pointer-wide-bitfield.h +++ b/bindgen-tests/tests/headers/issue-739-pointer-wide-bitfield.h @@ -1,3 +1,4 @@ +// bindgen-flags: --raw-line '#![cfg(not(target_os="windows"))]' #define POINTER_WIDTH (sizeof(void*) * 8) struct Foo { 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/issue-753.h b/bindgen-tests/tests/headers/issue-753.h new file mode 100644 index 0000000000..3a6c82528a --- /dev/null +++ b/bindgen-tests/tests/headers/issue-753.h @@ -0,0 +1,12 @@ +// bindgen-flags: --clang-macro-fallback + +#ifndef ISSUE_753_H +#define ISSUE_753_H + +#define UINT32_C(c) c ## U + +#define CONST UINT32_C(5) +#define OTHER_CONST UINT32_C(6) +#define LARGE_CONST UINT32_C(6 << 8) + +#endif diff --git a/tests/headers/issue-769-bad-instantiation-test.hpp b/bindgen-tests/tests/headers/issue-769-bad-instantiation-test.hpp similarity index 100% rename from tests/headers/issue-769-bad-instantiation-test.hpp rename to bindgen-tests/tests/headers/issue-769-bad-instantiation-test.hpp diff --git a/tests/headers/issue-801-opaque-sloppiness.hpp b/bindgen-tests/tests/headers/issue-801-opaque-sloppiness.hpp similarity index 100% rename from tests/headers/issue-801-opaque-sloppiness.hpp rename to bindgen-tests/tests/headers/issue-801-opaque-sloppiness.hpp diff --git a/tests/headers/issue-807-opaque-types-methods-being-generated.hpp b/bindgen-tests/tests/headers/issue-807-opaque-types-methods-being-generated.hpp similarity index 100% rename from tests/headers/issue-807-opaque-types-methods-being-generated.hpp rename to bindgen-tests/tests/headers/issue-807-opaque-types-methods-being-generated.hpp diff --git a/tests/headers/issue-816.h b/bindgen-tests/tests/headers/issue-816.h similarity index 100% rename from tests/headers/issue-816.h rename to bindgen-tests/tests/headers/issue-816.h diff --git a/tests/headers/issue-820-unused-template-param-in-alias.hpp b/bindgen-tests/tests/headers/issue-820-unused-template-param-in-alias.hpp similarity index 100% rename from tests/headers/issue-820-unused-template-param-in-alias.hpp rename to bindgen-tests/tests/headers/issue-820-unused-template-param-in-alias.hpp diff --git a/tests/headers/issue-826-generating-methods-when-asked-not-to.hpp b/bindgen-tests/tests/headers/issue-826-generating-methods-when-asked-not-to.hpp similarity index 100% rename from tests/headers/issue-826-generating-methods-when-asked-not-to.hpp rename to bindgen-tests/tests/headers/issue-826-generating-methods-when-asked-not-to.hpp diff --git a/tests/headers/issue-833-1.hpp b/bindgen-tests/tests/headers/issue-833-1.hpp similarity index 100% rename from tests/headers/issue-833-1.hpp rename to bindgen-tests/tests/headers/issue-833-1.hpp diff --git a/tests/headers/issue-833-2.hpp b/bindgen-tests/tests/headers/issue-833-2.hpp similarity index 100% rename from tests/headers/issue-833-2.hpp rename to bindgen-tests/tests/headers/issue-833-2.hpp diff --git a/tests/headers/issue-833.hpp b/bindgen-tests/tests/headers/issue-833.hpp similarity index 100% rename from tests/headers/issue-833.hpp rename to bindgen-tests/tests/headers/issue-833.hpp diff --git a/tests/headers/issue-834.hpp b/bindgen-tests/tests/headers/issue-834.hpp similarity index 100% rename from tests/headers/issue-834.hpp rename to bindgen-tests/tests/headers/issue-834.hpp diff --git a/tests/headers/issue-848-replacement-system-include.hpp b/bindgen-tests/tests/headers/issue-848-replacement-system-include.hpp similarity index 100% rename from tests/headers/issue-848-replacement-system-include.hpp rename to bindgen-tests/tests/headers/issue-848-replacement-system-include.hpp diff --git a/tests/headers/issue-848/an-include.h b/bindgen-tests/tests/headers/issue-848/an-include.h similarity index 100% rename from tests/headers/issue-848/an-include.h rename to bindgen-tests/tests/headers/issue-848/an-include.h diff --git a/tests/headers/issue-888-enum-var-decl-jump.hpp b/bindgen-tests/tests/headers/issue-888-enum-var-decl-jump.hpp similarity index 100% rename from tests/headers/issue-888-enum-var-decl-jump.hpp rename to bindgen-tests/tests/headers/issue-888-enum-var-decl-jump.hpp diff --git a/tests/headers/issue-944-derive-copy-and-blocklisting.hpp b/bindgen-tests/tests/headers/issue-944-derive-copy-and-blocklisting.hpp similarity index 100% rename from tests/headers/issue-944-derive-copy-and-blocklisting.hpp rename to bindgen-tests/tests/headers/issue-944-derive-copy-and-blocklisting.hpp diff --git a/tests/headers/issue-946.h b/bindgen-tests/tests/headers/issue-946.h similarity index 100% rename from tests/headers/issue-946.h rename to bindgen-tests/tests/headers/issue-946.h diff --git a/tests/headers/issue_311.hpp b/bindgen-tests/tests/headers/issue_311.hpp similarity index 100% rename from tests/headers/issue_311.hpp rename to bindgen-tests/tests/headers/issue_311.hpp diff --git a/tests/headers/issue_315.hpp b/bindgen-tests/tests/headers/issue_315.hpp similarity index 100% rename from tests/headers/issue_315.hpp rename to bindgen-tests/tests/headers/issue_315.hpp diff --git a/tests/headers/jsval_layout_opaque.hpp b/bindgen-tests/tests/headers/jsval_layout_opaque.hpp similarity index 100% rename from tests/headers/jsval_layout_opaque.hpp rename to bindgen-tests/tests/headers/jsval_layout_opaque.hpp diff --git a/tests/headers/keywords.h b/bindgen-tests/tests/headers/keywords.h similarity index 94% rename from tests/headers/keywords.h rename to bindgen-tests/tests/headers/keywords.h index d7fe2065b0..49924193c7 100644 --- a/tests/headers/keywords.h +++ b/bindgen-tests/tests/headers/keywords.h @@ -15,10 +15,13 @@ int str; int dyn; int as; +int async; +int await; int box; int crate; int false; int fn; +int gen; int impl; int in; int let; diff --git a/tests/headers/layout.h b/bindgen-tests/tests/headers/layout.h similarity index 85% rename from tests/headers/layout.h rename to bindgen-tests/tests/headers/layout.h index b290ee856b..06b7165ab9 100644 --- a/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/tests/headers/layout_align.h b/bindgen-tests/tests/headers/layout_align.h similarity index 100% rename from tests/headers/layout_align.h rename to bindgen-tests/tests/headers/layout_align.h diff --git a/tests/headers/layout_arp.h b/bindgen-tests/tests/headers/layout_arp.h similarity index 100% rename from tests/headers/layout_arp.h rename to bindgen-tests/tests/headers/layout_arp.h diff --git a/tests/headers/layout_array.h b/bindgen-tests/tests/headers/layout_array.h similarity index 98% rename from tests/headers/layout_array.h rename to bindgen-tests/tests/headers/layout_array.h index e6a57f7ca4..239e52b193 100644 --- a/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/tests/headers/layout_array_too_long.h b/bindgen-tests/tests/headers/layout_array_too_long.h similarity index 96% rename from tests/headers/layout_array_too_long.h rename to bindgen-tests/tests/headers/layout_array_too_long.h index 53e4d8bed4..d0d34ba038 100644 --- a/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/tests/headers/layout_cmdline_token.h b/bindgen-tests/tests/headers/layout_cmdline_token.h similarity index 100% rename from tests/headers/layout_cmdline_token.h rename to bindgen-tests/tests/headers/layout_cmdline_token.h diff --git a/tests/headers/layout_eth_conf.h b/bindgen-tests/tests/headers/layout_eth_conf.h similarity index 98% rename from tests/headers/layout_eth_conf.h rename to bindgen-tests/tests/headers/layout_eth_conf.h index 9446bffb4c..ec1a691985 100644 --- a/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; @@ -139,7 +139,7 @@ enum rte_eth_nb_pools { * 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 + * 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 @@ -151,7 +151,7 @@ struct rte_eth_vmdq_dcb_conf { 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 */ + 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]; @@ -189,7 +189,7 @@ struct rte_eth_vmdq_rx_conf { 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 */ + 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. */ }; diff --git a/tests/headers/layout_kni_mbuf.h b/bindgen-tests/tests/headers/layout_kni_mbuf.h similarity index 96% rename from tests/headers/layout_kni_mbuf.h rename to bindgen-tests/tests/headers/layout_kni_mbuf.h index 4d604aa6a8..148cb7df95 100644 --- a/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/tests/headers/layout_large_align_field.h b/bindgen-tests/tests/headers/layout_large_align_field.h similarity index 98% rename from tests/headers/layout_large_align_field.h rename to bindgen-tests/tests/headers/layout_large_align_field.h index 63aea90bd9..f292bb70dc 100644 --- a/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/tests/headers/layout_mbuf.h b/bindgen-tests/tests/headers/layout_mbuf.h similarity index 100% rename from tests/headers/layout_mbuf.h rename to bindgen-tests/tests/headers/layout_mbuf.h diff --git a/bindgen-tests/tests/headers/long_double.h b/bindgen-tests/tests/headers/long_double.h new file mode 100644 index 0000000000..341be37164 --- /dev/null +++ b/bindgen-tests/tests/headers/long_double.h @@ -0,0 +1,3 @@ +struct foo { + long double bar; +}; diff --git a/tests/headers/macro-expr-basic.h b/bindgen-tests/tests/headers/macro-expr-basic.h similarity index 100% rename from tests/headers/macro-expr-basic.h rename to bindgen-tests/tests/headers/macro-expr-basic.h diff --git a/tests/headers/macro-expr-uncommon-token.h b/bindgen-tests/tests/headers/macro-expr-uncommon-token.h similarity index 100% rename from tests/headers/macro-expr-uncommon-token.h rename to bindgen-tests/tests/headers/macro-expr-uncommon-token.h diff --git a/tests/headers/macro-redef.h b/bindgen-tests/tests/headers/macro-redef.h similarity index 100% rename from tests/headers/macro-redef.h rename to bindgen-tests/tests/headers/macro-redef.h diff --git a/tests/headers/macro_const.h b/bindgen-tests/tests/headers/macro_const.h similarity index 100% rename from tests/headers/macro_const.h rename to bindgen-tests/tests/headers/macro_const.h diff --git a/tests/headers/maddness-is-avoidable.hpp b/bindgen-tests/tests/headers/maddness-is-avoidable.hpp similarity index 100% rename from tests/headers/maddness-is-avoidable.hpp rename to bindgen-tests/tests/headers/maddness-is-avoidable.hpp diff --git a/tests/headers/mangling-ios.h b/bindgen-tests/tests/headers/mangling-ios.h similarity index 100% rename from tests/headers/mangling-ios.h rename to bindgen-tests/tests/headers/mangling-ios.h diff --git a/tests/headers/mangling-linux32.hpp b/bindgen-tests/tests/headers/mangling-linux32.hpp similarity index 100% rename from tests/headers/mangling-linux32.hpp rename to bindgen-tests/tests/headers/mangling-linux32.hpp diff --git a/tests/headers/mangling-linux64.hpp b/bindgen-tests/tests/headers/mangling-linux64.hpp similarity index 100% rename from tests/headers/mangling-linux64.hpp rename to bindgen-tests/tests/headers/mangling-linux64.hpp diff --git a/tests/headers/mangling-macos.hpp b/bindgen-tests/tests/headers/mangling-macos.hpp similarity index 100% rename from tests/headers/mangling-macos.hpp rename to bindgen-tests/tests/headers/mangling-macos.hpp diff --git a/tests/headers/mangling-win32.hpp b/bindgen-tests/tests/headers/mangling-win32.hpp similarity index 84% rename from tests/headers/mangling-win32.hpp rename to bindgen-tests/tests/headers/mangling-win32.hpp index 386df4aba3..76a7e664ed 100644 --- a/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/tests/headers/mangling-win64.hpp b/bindgen-tests/tests/headers/mangling-win64.hpp similarity index 100% rename from tests/headers/mangling-win64.hpp rename to bindgen-tests/tests/headers/mangling-win64.hpp diff --git a/bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp b/bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp new file mode 100644 index 0000000000..080979f17b --- /dev/null +++ b/bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp @@ -0,0 +1,14 @@ +// bindgen-flags: --merge-extern-blocks --enable-cxx-namespaces --rust-target=1.82 -- --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/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/tests/headers/method-mangling.hpp b/bindgen-tests/tests/headers/method-mangling.hpp similarity index 100% rename from tests/headers/method-mangling.hpp rename to bindgen-tests/tests/headers/method-mangling.hpp diff --git a/tests/headers/module-allowlisted.hpp b/bindgen-tests/tests/headers/module-allowlisted.hpp similarity index 100% rename from tests/headers/module-allowlisted.hpp rename to bindgen-tests/tests/headers/module-allowlisted.hpp diff --git a/tests/headers/msvc-no-usr.hpp b/bindgen-tests/tests/headers/msvc-no-usr.hpp similarity index 100% rename from tests/headers/msvc-no-usr.hpp rename to bindgen-tests/tests/headers/msvc-no-usr.hpp diff --git a/tests/headers/multiple-inherit-empty-correct-layout.hpp b/bindgen-tests/tests/headers/multiple-inherit-empty-correct-layout.hpp similarity index 100% rename from tests/headers/multiple-inherit-empty-correct-layout.hpp rename to bindgen-tests/tests/headers/multiple-inherit-empty-correct-layout.hpp diff --git a/tests/headers/mutable.hpp b/bindgen-tests/tests/headers/mutable.hpp similarity index 100% rename from tests/headers/mutable.hpp rename to bindgen-tests/tests/headers/mutable.hpp diff --git a/tests/headers/namespace.hpp b/bindgen-tests/tests/headers/namespace.hpp similarity index 100% rename from tests/headers/namespace.hpp rename to bindgen-tests/tests/headers/namespace.hpp diff --git a/tests/headers/namespace/nsbegin.h b/bindgen-tests/tests/headers/namespace/nsbegin.h similarity index 100% rename from tests/headers/namespace/nsbegin.h rename to bindgen-tests/tests/headers/namespace/nsbegin.h 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/tests/headers/namespace/nsend.h b/bindgen-tests/tests/headers/namespace/nsend.h similarity index 100% rename from tests/headers/namespace/nsend.h rename to bindgen-tests/tests/headers/namespace/nsend.h 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/tests/headers/nested-template-typedef.hpp b/bindgen-tests/tests/headers/nested-template-typedef.hpp similarity index 100% rename from tests/headers/nested-template-typedef.hpp rename to bindgen-tests/tests/headers/nested-template-typedef.hpp diff --git a/tests/headers/nested.hpp b/bindgen-tests/tests/headers/nested.hpp similarity index 100% rename from tests/headers/nested.hpp rename to bindgen-tests/tests/headers/nested.hpp diff --git a/tests/headers/nested_vtable.hpp b/bindgen-tests/tests/headers/nested_vtable.hpp similarity index 100% rename from tests/headers/nested_vtable.hpp rename to bindgen-tests/tests/headers/nested_vtable.hpp diff --git a/tests/headers/nested_within_namespace.hpp b/bindgen-tests/tests/headers/nested_within_namespace.hpp similarity index 100% rename from tests/headers/nested_within_namespace.hpp rename to bindgen-tests/tests/headers/nested_within_namespace.hpp 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 new file mode 100644 index 0000000000..e711ed85bc --- /dev/null +++ b/bindgen-tests/tests/headers/newtype-enum.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --newtype-enum "Foo" -- -std=c++11 + +enum Foo { + Bar = 1 << 1, + Baz = 1 << 2, + Duplicated = 1 << 2, + Negative = -3, +}; diff --git a/bindgen-tests/tests/headers/newtype-global-enum.hpp b/bindgen-tests/tests/headers/newtype-global-enum.hpp new file mode 100644 index 0000000000..c10825fdcf --- /dev/null +++ b/bindgen-tests/tests/headers/newtype-global-enum.hpp @@ -0,0 +1,8 @@ +// bindgen-flags: --newtype-global-enum "Foo" -- -std=c++11 + +enum Foo { + Bar = 1 << 1, + Baz = 1 << 2, + Duplicated = 1 << 2, + Negative = -3, +}; diff --git a/tests/headers/no-comments.h b/bindgen-tests/tests/headers/no-comments.h similarity index 100% rename from tests/headers/no-comments.h rename to bindgen-tests/tests/headers/no-comments.h diff --git a/tests/headers/no-derive-debug.h b/bindgen-tests/tests/headers/no-derive-debug.h similarity index 100% rename from tests/headers/no-derive-debug.h rename to bindgen-tests/tests/headers/no-derive-debug.h diff --git a/tests/headers/no-derive-default.h b/bindgen-tests/tests/headers/no-derive-default.h similarity index 100% rename from tests/headers/no-derive-default.h rename to bindgen-tests/tests/headers/no-derive-default.h diff --git a/tests/headers/no-hash-allowlisted.hpp b/bindgen-tests/tests/headers/no-hash-allowlisted.hpp similarity index 100% rename from tests/headers/no-hash-allowlisted.hpp rename to bindgen-tests/tests/headers/no-hash-allowlisted.hpp diff --git a/tests/headers/no-hash-opaque.hpp b/bindgen-tests/tests/headers/no-hash-opaque.hpp similarity index 100% rename from tests/headers/no-hash-opaque.hpp rename to bindgen-tests/tests/headers/no-hash-opaque.hpp diff --git a/tests/headers/no-partialeq-allowlisted.hpp b/bindgen-tests/tests/headers/no-partialeq-allowlisted.hpp similarity index 100% rename from tests/headers/no-partialeq-allowlisted.hpp rename to bindgen-tests/tests/headers/no-partialeq-allowlisted.hpp diff --git a/tests/headers/no-partialeq-opaque.hpp b/bindgen-tests/tests/headers/no-partialeq-opaque.hpp similarity index 100% rename from tests/headers/no-partialeq-opaque.hpp rename to bindgen-tests/tests/headers/no-partialeq-opaque.hpp diff --git a/tests/headers/no-recursive-allowlisting.h b/bindgen-tests/tests/headers/no-recursive-allowlisting.h similarity index 100% rename from tests/headers/no-recursive-allowlisting.h rename to bindgen-tests/tests/headers/no-recursive-allowlisting.h diff --git a/tests/headers/no-std.h b/bindgen-tests/tests/headers/no-std.h similarity index 100% rename from tests/headers/no-std.h rename to bindgen-tests/tests/headers/no-std.h diff --git a/tests/headers/no_copy.hpp b/bindgen-tests/tests/headers/no_copy.hpp similarity index 100% rename from tests/headers/no_copy.hpp rename to bindgen-tests/tests/headers/no_copy.hpp diff --git a/tests/headers/no_copy_allowlisted.hpp b/bindgen-tests/tests/headers/no_copy_allowlisted.hpp similarity index 100% rename from tests/headers/no_copy_allowlisted.hpp rename to bindgen-tests/tests/headers/no_copy_allowlisted.hpp diff --git a/tests/headers/no_copy_opaque.hpp b/bindgen-tests/tests/headers/no_copy_opaque.hpp similarity index 100% rename from tests/headers/no_copy_opaque.hpp rename to bindgen-tests/tests/headers/no_copy_opaque.hpp diff --git a/tests/headers/no_debug.hpp b/bindgen-tests/tests/headers/no_debug.hpp similarity index 100% rename from tests/headers/no_debug.hpp rename to bindgen-tests/tests/headers/no_debug.hpp diff --git a/tests/headers/no_debug_allowlisted.hpp b/bindgen-tests/tests/headers/no_debug_allowlisted.hpp similarity index 100% rename from tests/headers/no_debug_allowlisted.hpp rename to bindgen-tests/tests/headers/no_debug_allowlisted.hpp diff --git a/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp b/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp new file mode 100644 index 0000000000..a586441088 --- /dev/null +++ b/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp @@ -0,0 +1,11 @@ +// bindgen-flags: --no-debug "NoDebug" --impl-debug + +template +class Generic { + T t[40]; +}; + +template +class NoDebug { + T t[40]; +}; diff --git a/tests/headers/no_debug_opaque.hpp b/bindgen-tests/tests/headers/no_debug_opaque.hpp similarity index 100% rename from tests/headers/no_debug_opaque.hpp rename to bindgen-tests/tests/headers/no_debug_opaque.hpp diff --git a/tests/headers/no_default.hpp b/bindgen-tests/tests/headers/no_default.hpp similarity index 100% rename from tests/headers/no_default.hpp rename to bindgen-tests/tests/headers/no_default.hpp diff --git a/tests/headers/no_default_allowlisted.hpp b/bindgen-tests/tests/headers/no_default_allowlisted.hpp similarity index 100% rename from tests/headers/no_default_allowlisted.hpp rename to bindgen-tests/tests/headers/no_default_allowlisted.hpp diff --git a/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp b/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp new file mode 100644 index 0000000000..0f8339062f --- /dev/null +++ b/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp @@ -0,0 +1,11 @@ +// bindgen-flags: --no-default "NoDefault" + +template +class Generic { + T t[40]; +}; + +template +class NoDefault { + T t[40]; +}; diff --git a/tests/headers/no_default_opaque.hpp b/bindgen-tests/tests/headers/no_default_opaque.hpp similarity index 100% rename from tests/headers/no_default_opaque.hpp rename to bindgen-tests/tests/headers/no_default_opaque.hpp diff --git a/bindgen-tests/tests/headers/no_size_t_is_usize.h b/bindgen-tests/tests/headers/no_size_t_is_usize.h new file mode 100644 index 0000000000..d4370baf9f --- /dev/null +++ b/bindgen-tests/tests/headers/no_size_t_is_usize.h @@ -0,0 +1,10 @@ +// bindgen-flags: --no-size_t-is-usize + +typedef unsigned long size_t; +typedef long ssize_t; + +struct A { + size_t len; + ssize_t offset; + struct A* next; +}; diff --git a/tests/headers/non-type-params.hpp b/bindgen-tests/tests/headers/non-type-params.hpp similarity index 100% rename from tests/headers/non-type-params.hpp rename to bindgen-tests/tests/headers/non-type-params.hpp diff --git a/bindgen-tests/tests/headers/noreturn.hpp b/bindgen-tests/tests/headers/noreturn.hpp new file mode 100644 index 0000000000..bf9d58c7fa --- /dev/null +++ b/bindgen-tests/tests/headers/noreturn.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --enable-function-attribute-detection -- -std=c++11 +_Noreturn void f(void); +__attribute__((noreturn)) void g(void); +[[noreturn]] void h(void); +void i(__attribute__((noreturn)) void (*arg)(void)); +__attribute__((noreturn)) void j(__attribute__((noreturn)) void (*arg)(void)); diff --git a/tests/headers/nsBaseHashtable.hpp b/bindgen-tests/tests/headers/nsBaseHashtable.hpp similarity index 100% rename from tests/headers/nsBaseHashtable.hpp rename to bindgen-tests/tests/headers/nsBaseHashtable.hpp diff --git a/tests/headers/nsStyleAutoArray.hpp b/bindgen-tests/tests/headers/nsStyleAutoArray.hpp similarity index 100% rename from tests/headers/nsStyleAutoArray.hpp rename to bindgen-tests/tests/headers/nsStyleAutoArray.hpp diff --git a/tests/headers/objc_allowlist.h b/bindgen-tests/tests/headers/objc_allowlist.h similarity index 77% rename from tests/headers/objc_allowlist.h rename to bindgen-tests/tests/headers/objc_allowlist.h index 8c939960b0..b5406d0adf 100644 --- a/tests/headers/objc_allowlist.h +++ b/bindgen-tests/tests/headers/objc_allowlist.h @@ -1,4 +1,4 @@ -// bindgen-flags: --objc-extern-crate --allowlist-type AllowlistMe --allowlist-type AllowlistMe_InterestingCategory -- -x objective-c +// bindgen-flags: --allowlist-type IAllowlistMe --allowlist-type AllowlistMe_InterestingCategory -- -x objective-c // bindgen-osx-only diff --git a/bindgen-tests/tests/headers/objc_blocklist.h b/bindgen-tests/tests/headers/objc_blocklist.h new file mode 100644 index 0000000000..605f2993cf --- /dev/null +++ b/bindgen-tests/tests/headers/objc_blocklist.h @@ -0,0 +1,9 @@ +// bindgen-flags: --objc-extern-crate --blocklist-item ISomeClass::class_ambiguouslyBlockedMethod --blocklist-item ISomeClass::blockedInstanceMethod -- -x objective-c +// bindgen-osx-only + +@interface SomeClass ++ (void)ambiguouslyBlockedMethod; +- (void)ambiguouslyBlockedMethod; +- (void)instanceMethod; +- (void)blockedInstanceMethod; +@end diff --git a/bindgen-tests/tests/headers/objc_category.h b/bindgen-tests/tests/headers/objc_category.h new file mode 100644 index 0000000000..b8e60d5fa9 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_category.h @@ -0,0 +1,10 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo +-(void)method; +@end + +@interface Foo (BarCategory) +-(void)categoryMethod; +@end diff --git a/bindgen-tests/tests/headers/objc_class.h b/bindgen-tests/tests/headers/objc_class.h new file mode 100644 index 0000000000..f5ec950750 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_class.h @@ -0,0 +1,10 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@class Foo; + +Foo* fooVar; + +@interface Foo +-(void)method; +@end diff --git a/tests/headers/objc_class_method.h b/bindgen-tests/tests/headers/objc_class_method.h similarity index 82% rename from tests/headers/objc_class_method.h rename to bindgen-tests/tests/headers/objc_class_method.h index ddda742e8a..1a68ed3e6e 100644 --- a/tests/headers/objc_class_method.h +++ b/bindgen-tests/tests/headers/objc_class_method.h @@ -1,4 +1,4 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c +// bindgen-flags: -- -x objective-c // bindgen-osx-only @interface Foo diff --git a/bindgen-tests/tests/headers/objc_escape.h b/bindgen-tests/tests/headers/objc_escape.h new file mode 100644 index 0000000000..2d21bd5481 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_escape.h @@ -0,0 +1,13 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface A +-(void)f:(int)arg1 as:(int)arg2; +-(void)crate:(int)self; +@end + +@interface B + +@property(nonatomic, retain) id type; + +@end diff --git a/bindgen-tests/tests/headers/objc_inheritance.h b/bindgen-tests/tests/headers/objc_inheritance.h new file mode 100644 index 0000000000..985f1597e5 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_inheritance.h @@ -0,0 +1,11 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo +@end + +@interface Bar: Foo +@end + +@interface Baz: Bar +@end diff --git a/bindgen-tests/tests/headers/objc_interface.h b/bindgen-tests/tests/headers/objc_interface.h new file mode 100644 index 0000000000..df16e921ec --- /dev/null +++ b/bindgen-tests/tests/headers/objc_interface.h @@ -0,0 +1,8 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo +@end + +@protocol bar +@end diff --git a/bindgen-tests/tests/headers/objc_interface_type.h b/bindgen-tests/tests/headers/objc_interface_type.h new file mode 100644 index 0000000000..4667ce2a0c --- /dev/null +++ b/bindgen-tests/tests/headers/objc_interface_type.h @@ -0,0 +1,13 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo +@end + +struct FooStruct { + Foo *foo; +}; + +void fooFunc(Foo *foo); + +static const Foo *kFoo; diff --git a/tests/headers/objc_method.h b/bindgen-tests/tests/headers/objc_method.h similarity index 89% rename from tests/headers/objc_method.h rename to bindgen-tests/tests/headers/objc_method.h index c4d375bac0..b89d1621b1 100644 --- a/tests/headers/objc_method.h +++ b/bindgen-tests/tests/headers/objc_method.h @@ -1,4 +1,4 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c +// bindgen-flags: -- -x objective-c // bindgen-osx-only @interface Foo diff --git a/bindgen-tests/tests/headers/objc_method_clash.h b/bindgen-tests/tests/headers/objc_method_clash.h new file mode 100644 index 0000000000..d99d3691fe --- /dev/null +++ b/bindgen-tests/tests/headers/objc_method_clash.h @@ -0,0 +1,7 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo ++ (void)foo; +- (void)foo; +@end diff --git a/bindgen-tests/tests/headers/objc_pointer_return_types.h b/bindgen-tests/tests/headers/objc_pointer_return_types.h new file mode 100644 index 0000000000..4d1a6dea34 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_pointer_return_types.h @@ -0,0 +1,10 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Bar +@end + +@interface Foo ++ (Bar*)methodReturningBar; +- (void)methodUsingBar:(Bar *)my_bar; +@end diff --git a/bindgen-tests/tests/headers/objc_property_fnptr.h b/bindgen-tests/tests/headers/objc_property_fnptr.h new file mode 100644 index 0000000000..fe3e7fcc99 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_property_fnptr.h @@ -0,0 +1,6 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface Foo +@property int (*func)(char, short, float); +@end diff --git a/bindgen-tests/tests/headers/objc_protocol.h b/bindgen-tests/tests/headers/objc_protocol.h new file mode 100644 index 0000000000..46978a3b4e --- /dev/null +++ b/bindgen-tests/tests/headers/objc_protocol.h @@ -0,0 +1,8 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@protocol Foo +@end + +@interface Foo +@end diff --git a/bindgen-tests/tests/headers/objc_protocol_inheritance.h b/bindgen-tests/tests/headers/objc_protocol_inheritance.h new file mode 100644 index 0000000000..13135fddbc --- /dev/null +++ b/bindgen-tests/tests/headers/objc_protocol_inheritance.h @@ -0,0 +1,11 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@protocol Foo +@end + +@interface Foo +@end + +@interface Bar : Foo +@end diff --git a/bindgen-tests/tests/headers/objc_sel_and_id.h b/bindgen-tests/tests/headers/objc_sel_and_id.h new file mode 100644 index 0000000000..6491a541c6 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_sel_and_id.h @@ -0,0 +1,7 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +id object; +SEL selector; + +void f(id object, SEL selector); diff --git a/tests/headers/objc_template.h b/bindgen-tests/tests/headers/objc_template.h similarity index 79% rename from tests/headers/objc_template.h rename to bindgen-tests/tests/headers/objc_template.h index a4d0055c16..b616da013f 100644 --- a/tests/headers/objc_template.h +++ b/bindgen-tests/tests/headers/objc_template.h @@ -1,4 +1,4 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c +// bindgen-flags: -- -x objective-c // bindgen-osx-only @interface Foo<__covariant ObjectType> diff --git a/tests/headers/only_bitfields.hpp b/bindgen-tests/tests/headers/only_bitfields.hpp similarity index 100% rename from tests/headers/only_bitfields.hpp rename to bindgen-tests/tests/headers/only_bitfields.hpp diff --git a/tests/headers/opaque-template-inst-member-2.hpp b/bindgen-tests/tests/headers/opaque-template-inst-member-2.hpp similarity index 100% rename from tests/headers/opaque-template-inst-member-2.hpp rename to bindgen-tests/tests/headers/opaque-template-inst-member-2.hpp diff --git a/tests/headers/opaque-template-inst-member.hpp b/bindgen-tests/tests/headers/opaque-template-inst-member.hpp similarity index 88% rename from tests/headers/opaque-template-inst-member.hpp rename to bindgen-tests/tests/headers/opaque-template-inst-member.hpp index 9b327919c1..6516aa564d 100644 --- a/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/tests/headers/opaque-template-instantiation-namespaced.hpp b/bindgen-tests/tests/headers/opaque-template-instantiation-namespaced.hpp similarity index 100% rename from tests/headers/opaque-template-instantiation-namespaced.hpp rename to bindgen-tests/tests/headers/opaque-template-instantiation-namespaced.hpp diff --git a/tests/headers/opaque-template-instantiation.hpp b/bindgen-tests/tests/headers/opaque-template-instantiation.hpp similarity index 100% rename from tests/headers/opaque-template-instantiation.hpp rename to bindgen-tests/tests/headers/opaque-template-instantiation.hpp diff --git a/tests/headers/opaque-tracing.hpp b/bindgen-tests/tests/headers/opaque-tracing.hpp similarity index 100% rename from tests/headers/opaque-tracing.hpp rename to bindgen-tests/tests/headers/opaque-tracing.hpp diff --git a/tests/headers/opaque_in_struct.hpp b/bindgen-tests/tests/headers/opaque_in_struct.hpp similarity index 100% rename from tests/headers/opaque_in_struct.hpp rename to bindgen-tests/tests/headers/opaque_in_struct.hpp diff --git a/tests/headers/opaque_pointer.hpp b/bindgen-tests/tests/headers/opaque_pointer.hpp similarity index 100% rename from tests/headers/opaque_pointer.hpp rename to bindgen-tests/tests/headers/opaque_pointer.hpp diff --git a/tests/headers/opaque_typedef.hpp b/bindgen-tests/tests/headers/opaque_typedef.hpp similarity index 100% rename from tests/headers/opaque_typedef.hpp rename to bindgen-tests/tests/headers/opaque_typedef.hpp 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/tests/headers/operator.hpp b/bindgen-tests/tests/headers/operator.hpp similarity index 100% rename from tests/headers/operator.hpp rename to bindgen-tests/tests/headers/operator.hpp 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/ord-enum.h b/bindgen-tests/tests/headers/ord-enum.h new file mode 100644 index 0000000000..b14e77c2f8 --- /dev/null +++ b/bindgen-tests/tests/headers/ord-enum.h @@ -0,0 +1,15 @@ +// bindgen-flags: --rustified-enum ".*" --with-derive-ord + +enum A { + A0 = 0, + A1 = 1, + A2 = 2, + A3 = A0 - 1, +}; + +enum B { + B0 = 1, + B1 = B0 + 3, + B2 = B0 + 2, + B3 = B0 - 2, +}; diff --git a/tests/headers/overflowed_enum.hpp b/bindgen-tests/tests/headers/overflowed_enum.hpp similarity index 100% rename from tests/headers/overflowed_enum.hpp rename to bindgen-tests/tests/headers/overflowed_enum.hpp diff --git a/tests/headers/overloading.hpp b/bindgen-tests/tests/headers/overloading.hpp similarity index 100% rename from tests/headers/overloading.hpp rename to bindgen-tests/tests/headers/overloading.hpp diff --git a/tests/headers/packed-bitfield.h b/bindgen-tests/tests/headers/packed-bitfield.h similarity index 100% rename from tests/headers/packed-bitfield.h rename to bindgen-tests/tests/headers/packed-bitfield.h diff --git a/tests/headers/packed-n-with-padding.h b/bindgen-tests/tests/headers/packed-n-with-padding.h similarity index 100% rename from tests/headers/packed-n-with-padding.h rename to bindgen-tests/tests/headers/packed-n-with-padding.h diff --git a/bindgen-tests/tests/headers/packed-vtable.h b/bindgen-tests/tests/headers/packed-vtable.h new file mode 100644 index 0000000000..b3405977b5 --- /dev/null +++ b/bindgen-tests/tests/headers/packed-vtable.h @@ -0,0 +1,10 @@ +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' -- -x c++ -std=c++11 + +#pragma pack(1) + +// This should be packed. +struct PackedVtable { + virtual ~PackedVtable(); +}; + +#pragma pack() diff --git a/tests/headers/parm-union.hpp b/bindgen-tests/tests/headers/parm-union.hpp similarity index 100% rename from tests/headers/parm-union.hpp rename to bindgen-tests/tests/headers/parm-union.hpp diff --git a/tests/headers/parsecb-anonymous-enum-variant-rename.h b/bindgen-tests/tests/headers/parsecb-anonymous-enum-variant-rename.h similarity index 100% rename from tests/headers/parsecb-anonymous-enum-variant-rename.h rename to bindgen-tests/tests/headers/parsecb-anonymous-enum-variant-rename.h diff --git a/tests/headers/partial-specialization-and-inheritance.hpp b/bindgen-tests/tests/headers/partial-specialization-and-inheritance.hpp similarity index 100% rename from tests/headers/partial-specialization-and-inheritance.hpp rename to bindgen-tests/tests/headers/partial-specialization-and-inheritance.hpp diff --git a/bindgen-tests/tests/headers/pointer-attr.h b/bindgen-tests/tests/headers/pointer-attr.h new file mode 100644 index 0000000000..fe0004b8bf --- /dev/null +++ b/bindgen-tests/tests/headers/pointer-attr.h @@ -0,0 +1 @@ +void a(const char __attribute__((btf_type_tag("a"))) *); diff --git a/bindgen-tests/tests/headers/prefix-link-name-c.h b/bindgen-tests/tests/headers/prefix-link-name-c.h new file mode 100644 index 0000000000..2432798fce --- /dev/null +++ b/bindgen-tests/tests/headers/prefix-link-name-c.h @@ -0,0 +1,4 @@ +// bindgen-parse-callbacks: prefix-link-name-foo_ +// bindgen-flags: --prefix-link-name foo_ + +int bar(void); diff --git a/bindgen-tests/tests/headers/prefix-link-name-cpp.hpp b/bindgen-tests/tests/headers/prefix-link-name-cpp.hpp new file mode 100644 index 0000000000..4fd2612327 --- /dev/null +++ b/bindgen-tests/tests/headers/prefix-link-name-cpp.hpp @@ -0,0 +1,8 @@ +// bindgen-parse-callbacks: prefix-link-name-foo_ +// bindgen-flags: --prefix-link-name foo_ + +namespace baz { + +int foo(); + +} // end namespace baz diff --git a/tests/headers/prepend-enum-constified-variant.h b/bindgen-tests/tests/headers/prepend-enum-constified-variant.h similarity index 100% rename from tests/headers/prepend-enum-constified-variant.h rename to bindgen-tests/tests/headers/prepend-enum-constified-variant.h diff --git a/tests/headers/prepend_enum_name.hpp b/bindgen-tests/tests/headers/prepend_enum_name.hpp similarity index 100% rename from tests/headers/prepend_enum_name.hpp rename to bindgen-tests/tests/headers/prepend_enum_name.hpp diff --git a/tests/headers/private.hpp b/bindgen-tests/tests/headers/private.hpp similarity index 100% rename from tests/headers/private.hpp rename to bindgen-tests/tests/headers/private.hpp diff --git a/bindgen-tests/tests/headers/private_fields.hpp b/bindgen-tests/tests/headers/private_fields.hpp new file mode 100644 index 0000000000..965acde9e8 --- /dev/null +++ b/bindgen-tests/tests/headers/private_fields.hpp @@ -0,0 +1,63 @@ +// bindgen-flags: --respect-cxx-access-specs +// bindgen-parse-callbacks: field-visibility-default-public + +class PubPriv { + public: + int x; + private: + int y; +}; + +class PrivateBitFields { + unsigned int a : 4; + unsigned int b : 4; +}; +class PublicBitFields { + public: + unsigned int a : 4; + unsigned int b : 4; +}; +class MixedBitFields { + unsigned int a : 4; + public: + unsigned int d : 4; +}; + +class Base { + public: + int member; +}; + +class InheritsPrivately : Base {}; +class InheritsPublically : public Base {}; + +class WithAnonStruct { + struct { + int a; + }; + public: + struct { + int b; + }; +}; + +class WithAnonUnion { + union {}; +}; + +class Override { + public: + unsigned int a; + // override with annotation + /**
*/ + unsigned int b; + // override with callback + unsigned int private_c; + + unsigned int bf_a : 4; + // override with annotation + /**
*/ + unsigned int bf_b : 4; + // override with callback + unsigned int private_bf_c : 4; +}; diff --git a/bindgen-tests/tests/headers/ptr32-has-different-size.h b/bindgen-tests/tests/headers/ptr32-has-different-size.h new file mode 100644 index 0000000000..8cda702c53 --- /dev/null +++ b/bindgen-tests/tests/headers/ptr32-has-different-size.h @@ -0,0 +1,4 @@ +// bindgen-flags: -- -fms-extensions +typedef struct TEST_STRUCT { + void* __ptr32 ptr_32bit; +} TEST; diff --git a/bindgen-tests/tests/headers/public-dtor.hpp b/bindgen-tests/tests/headers/public-dtor.hpp new file mode 100644 index 0000000000..60d69d799f --- /dev/null +++ b/bindgen-tests/tests/headers/public-dtor.hpp @@ -0,0 +1,18 @@ + +namespace cv { + class Foo { + public: + ~Foo(); + }; + + Foo::~Foo() {} + + class Bar { + public: + ~Bar(); + }; + + inline + Bar::~Bar() {} + +} diff --git a/tests/headers/qualified-dependent-types.hpp b/bindgen-tests/tests/headers/qualified-dependent-types.hpp similarity index 100% rename from tests/headers/qualified-dependent-types.hpp rename to bindgen-tests/tests/headers/qualified-dependent-types.hpp diff --git a/tests/headers/redeclaration.hpp b/bindgen-tests/tests/headers/redeclaration.hpp similarity index 100% rename from tests/headers/redeclaration.hpp rename to bindgen-tests/tests/headers/redeclaration.hpp diff --git a/bindgen-tests/tests/headers/redundant-packed-and-align.h b/bindgen-tests/tests/headers/redundant-packed-and-align.h new file mode 100644 index 0000000000..75e15e4139 --- /dev/null +++ b/bindgen-tests/tests/headers/redundant-packed-and-align.h @@ -0,0 +1,42 @@ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +struct redundant_packed { + uint32_t a; + uint32_t b; +} __attribute__((packed, aligned(8))); + +struct redundant_packed_bitfield { + uint8_t a[3]; + uint8_t b0:1; + uint8_t b1:1; + uint32_t c; +} __attribute__((packed, aligned(8))); + + +union redundant_packed_union { + uint64_t a; + uint32_t b; +} __attribute__((packed, aligned(16))); + + +struct inner { + uint8_t a; +} __attribute__((packed, aligned(2))); + +struct outer_redundant_packed { + struct inner a[2]; + uint32_t b; +} __attribute__((packed, aligned(8))); + + +#pragma pack(2) + +struct redundant_pragma_packed { + uint8_t a; + uint16_t b; +} __attribute__((aligned(4))); + +#pragma pack() diff --git a/tests/headers/ref_argument_array.hpp b/bindgen-tests/tests/headers/ref_argument_array.hpp similarity index 100% rename from tests/headers/ref_argument_array.hpp rename to bindgen-tests/tests/headers/ref_argument_array.hpp 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/tests/headers/reparented_replacement.hpp b/bindgen-tests/tests/headers/reparented_replacement.hpp similarity index 100% rename from tests/headers/reparented_replacement.hpp rename to bindgen-tests/tests/headers/reparented_replacement.hpp diff --git a/tests/headers/replace_template_alias.hpp b/bindgen-tests/tests/headers/replace_template_alias.hpp similarity index 100% rename from tests/headers/replace_template_alias.hpp rename to bindgen-tests/tests/headers/replace_template_alias.hpp diff --git a/tests/headers/replace_use.hpp b/bindgen-tests/tests/headers/replace_use.hpp similarity index 100% rename from tests/headers/replace_use.hpp rename to bindgen-tests/tests/headers/replace_use.hpp diff --git a/tests/headers/replaces_double.hpp b/bindgen-tests/tests/headers/replaces_double.hpp similarity index 100% rename from tests/headers/replaces_double.hpp rename to bindgen-tests/tests/headers/replaces_double.hpp diff --git a/bindgen-tests/tests/headers/repr-align.hpp b/bindgen-tests/tests/headers/repr-align.hpp new file mode 100644 index 0000000000..a7719e10ed --- /dev/null +++ b/bindgen-tests/tests/headers/repr-align.hpp @@ -0,0 +1,11 @@ +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' -- -std=c++11 + +struct alignas(8) a { + int b; + int c; +}; + +struct alignas(double) b { + int b; + int c; +}; diff --git a/tests/headers/resolved_type_def_function.h b/bindgen-tests/tests/headers/resolved_type_def_function.h similarity index 100% rename from tests/headers/resolved_type_def_function.h rename to bindgen-tests/tests/headers/resolved_type_def_function.h diff --git a/tests/headers/same_struct_name_in_different_namespaces.hpp b/bindgen-tests/tests/headers/same_struct_name_in_different_namespaces.hpp similarity index 100% rename from tests/headers/same_struct_name_in_different_namespaces.hpp rename to bindgen-tests/tests/headers/same_struct_name_in_different_namespaces.hpp diff --git a/tests/headers/sentry-defined-multiple-times.hpp b/bindgen-tests/tests/headers/sentry-defined-multiple-times.hpp similarity index 100% rename from tests/headers/sentry-defined-multiple-times.hpp rename to bindgen-tests/tests/headers/sentry-defined-multiple-times.hpp diff --git a/tests/headers/short-enums.hpp b/bindgen-tests/tests/headers/short-enums.hpp similarity index 100% rename from tests/headers/short-enums.hpp rename to bindgen-tests/tests/headers/short-enums.hpp diff --git a/tests/headers/size_t_template.hpp b/bindgen-tests/tests/headers/size_t_template.hpp similarity index 100% rename from tests/headers/size_t_template.hpp rename to bindgen-tests/tests/headers/size_t_template.hpp diff --git a/bindgen-tests/tests/headers/sorted_items.hpp b/bindgen-tests/tests/headers/sorted_items.hpp new file mode 100644 index 0000000000..9b5ced9637 --- /dev/null +++ b/bindgen-tests/tests/headers/sorted_items.hpp @@ -0,0 +1,35 @@ +// bindgen-flags: --sort-semantically --enable-cxx-namespaces -- --target=x86_64-unknown-linux + +int foo(); +typedef int number; +int bar(number x); +struct Point +{ + number x; + number y; +}; +struct Angle +{ + number a; + number b; +}; +int baz(struct Point point); +const number NUMBER = 42; + +namespace ns { + int foo(); + typedef int number; + int bar(number x); + struct Point + { + number x; + number y; + }; + struct Angle + { + number a; + number b; + }; + int baz(struct Point point); + const number NUMBER = 42; +} 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/stdint_typedef.h b/bindgen-tests/tests/headers/stdint_typedef.h new file mode 100644 index 0000000000..f716a7f1a0 --- /dev/null +++ b/bindgen-tests/tests/headers/stdint_typedef.h @@ -0,0 +1,10 @@ +// bindgen-flags: --allowlist-type="Struct" --allowlist-function="fun" + +// no typedef should be emitted for `__uint64_t` +typedef unsigned long long __uint64_t; +typedef __uint64_t uint64_t; + +uint64_t fun(); +struct Struct { + uint64_t field; +}; diff --git a/bindgen-tests/tests/headers/strings_array.h b/bindgen-tests/tests/headers/strings_array.h new file mode 100644 index 0000000000..fa7bf561fa --- /dev/null +++ b/bindgen-tests/tests/headers/strings_array.h @@ -0,0 +1,3 @@ +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_cstr.h b/bindgen-tests/tests/headers/strings_cstr.h new file mode 100644 index 0000000000..8b1d40e689 --- /dev/null +++ b/bindgen-tests/tests/headers/strings_cstr.h @@ -0,0 +1,5 @@ +// bindgen-flags: --rust-target=1.59 --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.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/tests/headers/struct_containing_forward_declared_struct.h b/bindgen-tests/tests/headers/struct_containing_forward_declared_struct.h similarity index 100% rename from tests/headers/struct_containing_forward_declared_struct.h rename to bindgen-tests/tests/headers/struct_containing_forward_declared_struct.h diff --git a/tests/headers/struct_typedef.h b/bindgen-tests/tests/headers/struct_typedef.h similarity index 100% rename from tests/headers/struct_typedef.h rename to bindgen-tests/tests/headers/struct_typedef.h diff --git a/tests/headers/struct_typedef_ns.hpp b/bindgen-tests/tests/headers/struct_typedef_ns.hpp similarity index 100% rename from tests/headers/struct_typedef_ns.hpp rename to bindgen-tests/tests/headers/struct_typedef_ns.hpp diff --git a/tests/headers/struct_with_anon_struct.h b/bindgen-tests/tests/headers/struct_with_anon_struct.h similarity index 100% rename from tests/headers/struct_with_anon_struct.h rename to bindgen-tests/tests/headers/struct_with_anon_struct.h diff --git a/tests/headers/struct_with_anon_struct_array.h b/bindgen-tests/tests/headers/struct_with_anon_struct_array.h similarity index 100% rename from tests/headers/struct_with_anon_struct_array.h rename to bindgen-tests/tests/headers/struct_with_anon_struct_array.h diff --git a/tests/headers/struct_with_anon_struct_pointer.h b/bindgen-tests/tests/headers/struct_with_anon_struct_pointer.h similarity index 100% rename from tests/headers/struct_with_anon_struct_pointer.h rename to bindgen-tests/tests/headers/struct_with_anon_struct_pointer.h diff --git a/tests/headers/struct_with_anon_union.h b/bindgen-tests/tests/headers/struct_with_anon_union.h similarity index 100% rename from tests/headers/struct_with_anon_union.h rename to bindgen-tests/tests/headers/struct_with_anon_union.h diff --git a/tests/headers/struct_with_anon_unnamed_struct.h b/bindgen-tests/tests/headers/struct_with_anon_unnamed_struct.h similarity index 100% rename from tests/headers/struct_with_anon_unnamed_struct.h rename to bindgen-tests/tests/headers/struct_with_anon_unnamed_struct.h diff --git a/tests/headers/struct_with_anon_unnamed_union.h b/bindgen-tests/tests/headers/struct_with_anon_unnamed_union.h similarity index 100% rename from tests/headers/struct_with_anon_unnamed_union.h rename to bindgen-tests/tests/headers/struct_with_anon_unnamed_union.h diff --git a/tests/headers/struct_with_bitfields.h b/bindgen-tests/tests/headers/struct_with_bitfields.h similarity index 100% rename from tests/headers/struct_with_bitfields.h rename to bindgen-tests/tests/headers/struct_with_bitfields.h diff --git a/tests/headers/struct_with_derive_debug.h b/bindgen-tests/tests/headers/struct_with_derive_debug.h similarity index 88% rename from tests/headers/struct_with_derive_debug.h rename to bindgen-tests/tests/headers/struct_with_derive_debug.h index 4dc816b787..201748d9c5 100644 --- a/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/tests/headers/struct_with_large_array.hpp b/bindgen-tests/tests/headers/struct_with_large_array.hpp similarity index 83% rename from tests/headers/struct_with_large_array.hpp rename to bindgen-tests/tests/headers/struct_with_large_array.hpp index 974ca526a3..58e8e4d19a 100644 --- a/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/tests/headers/struct_with_nesting.h b/bindgen-tests/tests/headers/struct_with_nesting.h similarity index 100% rename from tests/headers/struct_with_nesting.h rename to bindgen-tests/tests/headers/struct_with_nesting.h diff --git a/tests/headers/struct_with_packing.h b/bindgen-tests/tests/headers/struct_with_packing.h similarity index 100% rename from tests/headers/struct_with_packing.h rename to bindgen-tests/tests/headers/struct_with_packing.h diff --git a/tests/headers/struct_with_struct.h b/bindgen-tests/tests/headers/struct_with_struct.h similarity index 100% rename from tests/headers/struct_with_struct.h rename to bindgen-tests/tests/headers/struct_with_struct.h diff --git a/tests/headers/struct_with_typedef_template_arg.hpp b/bindgen-tests/tests/headers/struct_with_typedef_template_arg.hpp similarity index 100% rename from tests/headers/struct_with_typedef_template_arg.hpp rename to bindgen-tests/tests/headers/struct_with_typedef_template_arg.hpp diff --git a/tests/headers/template-fun-ty.hpp b/bindgen-tests/tests/headers/template-fun-ty.hpp similarity index 100% rename from tests/headers/template-fun-ty.hpp rename to bindgen-tests/tests/headers/template-fun-ty.hpp diff --git a/tests/headers/template-param-usage-0.hpp b/bindgen-tests/tests/headers/template-param-usage-0.hpp similarity index 100% rename from tests/headers/template-param-usage-0.hpp rename to bindgen-tests/tests/headers/template-param-usage-0.hpp diff --git a/tests/headers/template-param-usage-1.hpp b/bindgen-tests/tests/headers/template-param-usage-1.hpp similarity index 100% rename from tests/headers/template-param-usage-1.hpp rename to bindgen-tests/tests/headers/template-param-usage-1.hpp diff --git a/tests/headers/template-param-usage-10.hpp b/bindgen-tests/tests/headers/template-param-usage-10.hpp similarity index 100% rename from tests/headers/template-param-usage-10.hpp rename to bindgen-tests/tests/headers/template-param-usage-10.hpp diff --git a/tests/headers/template-param-usage-11.hpp b/bindgen-tests/tests/headers/template-param-usage-11.hpp similarity index 100% rename from tests/headers/template-param-usage-11.hpp rename to bindgen-tests/tests/headers/template-param-usage-11.hpp diff --git a/tests/headers/template-param-usage-12.hpp b/bindgen-tests/tests/headers/template-param-usage-12.hpp similarity index 100% rename from tests/headers/template-param-usage-12.hpp rename to bindgen-tests/tests/headers/template-param-usage-12.hpp diff --git a/tests/headers/template-param-usage-13.hpp b/bindgen-tests/tests/headers/template-param-usage-13.hpp similarity index 100% rename from tests/headers/template-param-usage-13.hpp rename to bindgen-tests/tests/headers/template-param-usage-13.hpp diff --git a/tests/headers/template-param-usage-14.hpp b/bindgen-tests/tests/headers/template-param-usage-14.hpp similarity index 100% rename from tests/headers/template-param-usage-14.hpp rename to bindgen-tests/tests/headers/template-param-usage-14.hpp diff --git a/tests/headers/template-param-usage-15.hpp b/bindgen-tests/tests/headers/template-param-usage-15.hpp similarity index 100% rename from tests/headers/template-param-usage-15.hpp rename to bindgen-tests/tests/headers/template-param-usage-15.hpp diff --git a/tests/headers/template-param-usage-2.hpp b/bindgen-tests/tests/headers/template-param-usage-2.hpp similarity index 100% rename from tests/headers/template-param-usage-2.hpp rename to bindgen-tests/tests/headers/template-param-usage-2.hpp diff --git a/tests/headers/template-param-usage-3.hpp b/bindgen-tests/tests/headers/template-param-usage-3.hpp similarity index 100% rename from tests/headers/template-param-usage-3.hpp rename to bindgen-tests/tests/headers/template-param-usage-3.hpp diff --git a/tests/headers/template-param-usage-4.hpp b/bindgen-tests/tests/headers/template-param-usage-4.hpp similarity index 100% rename from tests/headers/template-param-usage-4.hpp rename to bindgen-tests/tests/headers/template-param-usage-4.hpp diff --git a/tests/headers/template-param-usage-5.hpp b/bindgen-tests/tests/headers/template-param-usage-5.hpp similarity index 100% rename from tests/headers/template-param-usage-5.hpp rename to bindgen-tests/tests/headers/template-param-usage-5.hpp diff --git a/tests/headers/template-param-usage-6.hpp b/bindgen-tests/tests/headers/template-param-usage-6.hpp similarity index 100% rename from tests/headers/template-param-usage-6.hpp rename to bindgen-tests/tests/headers/template-param-usage-6.hpp diff --git a/tests/headers/template-param-usage-7.hpp b/bindgen-tests/tests/headers/template-param-usage-7.hpp similarity index 76% rename from tests/headers/template-param-usage-7.hpp rename to bindgen-tests/tests/headers/template-param-usage-7.hpp index 99d4cc71b4..3d70cee145 100644 --- a/tests/headers/template-param-usage-7.hpp +++ b/bindgen-tests/tests/headers/template-param-usage-7.hpp @@ -6,5 +6,5 @@ class DoesNotUseU { V v; }; -// The bool should go away becuase U is not used. +// The bool should go away because U is not used. using Alias = DoesNotUseU; diff --git a/tests/headers/template-param-usage-8.hpp b/bindgen-tests/tests/headers/template-param-usage-8.hpp similarity index 100% rename from tests/headers/template-param-usage-8.hpp rename to bindgen-tests/tests/headers/template-param-usage-8.hpp diff --git a/tests/headers/template-param-usage-9.hpp b/bindgen-tests/tests/headers/template-param-usage-9.hpp similarity index 100% rename from tests/headers/template-param-usage-9.hpp rename to bindgen-tests/tests/headers/template-param-usage-9.hpp diff --git a/tests/headers/template-with-var.hpp b/bindgen-tests/tests/headers/template-with-var.hpp similarity index 100% rename from tests/headers/template-with-var.hpp rename to bindgen-tests/tests/headers/template-with-var.hpp diff --git a/tests/headers/template.hpp b/bindgen-tests/tests/headers/template.hpp similarity index 95% rename from tests/headers/template.hpp rename to bindgen-tests/tests/headers/template.hpp index eea2c4def5..bc32a357e8 100644 --- a/tests/headers/template.hpp +++ b/bindgen-tests/tests/headers/template.hpp @@ -32,9 +32,7 @@ struct C { B mBConstRef; B mPtrRef; B mArrayRef; - // clang 3.x ignores const in this case, so they generate different - // result than clang 4.0. - // B mBConstArray; + B mBConstArray; }; template diff --git a/tests/headers/template_alias.hpp b/bindgen-tests/tests/headers/template_alias.hpp similarity index 100% rename from tests/headers/template_alias.hpp rename to bindgen-tests/tests/headers/template_alias.hpp diff --git a/tests/headers/template_alias_basic.hpp b/bindgen-tests/tests/headers/template_alias_basic.hpp similarity index 100% rename from tests/headers/template_alias_basic.hpp rename to bindgen-tests/tests/headers/template_alias_basic.hpp diff --git a/tests/headers/template_alias_namespace.hpp b/bindgen-tests/tests/headers/template_alias_namespace.hpp similarity index 100% rename from tests/headers/template_alias_namespace.hpp rename to bindgen-tests/tests/headers/template_alias_namespace.hpp diff --git a/tests/headers/template_fun.hpp b/bindgen-tests/tests/headers/template_fun.hpp similarity index 100% rename from tests/headers/template_fun.hpp rename to bindgen-tests/tests/headers/template_fun.hpp diff --git a/tests/headers/template_instantiation_with_fn_local_type.hpp b/bindgen-tests/tests/headers/template_instantiation_with_fn_local_type.hpp similarity index 100% rename from tests/headers/template_instantiation_with_fn_local_type.hpp rename to bindgen-tests/tests/headers/template_instantiation_with_fn_local_type.hpp diff --git a/tests/headers/template_partial_specification.hpp b/bindgen-tests/tests/headers/template_partial_specification.hpp similarity index 100% rename from tests/headers/template_partial_specification.hpp rename to bindgen-tests/tests/headers/template_partial_specification.hpp diff --git a/tests/headers/template_typedef_transitive_param.hpp b/bindgen-tests/tests/headers/template_typedef_transitive_param.hpp similarity index 100% rename from tests/headers/template_typedef_transitive_param.hpp rename to bindgen-tests/tests/headers/template_typedef_transitive_param.hpp diff --git a/tests/headers/template_typedefs.hpp b/bindgen-tests/tests/headers/template_typedefs.hpp similarity index 100% rename from tests/headers/template_typedefs.hpp rename to bindgen-tests/tests/headers/template_typedefs.hpp diff --git a/tests/headers/templateref_opaque.hpp b/bindgen-tests/tests/headers/templateref_opaque.hpp similarity index 100% rename from tests/headers/templateref_opaque.hpp rename to bindgen-tests/tests/headers/templateref_opaque.hpp diff --git a/tests/headers/templatized-bitfield.hpp b/bindgen-tests/tests/headers/templatized-bitfield.hpp similarity index 100% rename from tests/headers/templatized-bitfield.hpp rename to bindgen-tests/tests/headers/templatized-bitfield.hpp diff --git a/tests/headers/timex.h b/bindgen-tests/tests/headers/timex.h similarity index 100% rename from tests/headers/timex.h rename to bindgen-tests/tests/headers/timex.h diff --git a/tests/headers/transform-op.hpp b/bindgen-tests/tests/headers/transform-op.hpp similarity index 94% rename from tests/headers/transform-op.hpp rename to bindgen-tests/tests/headers/transform-op.hpp index aa6118eb67..090e88b34b 100644 --- a/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/tests/headers/type-referenced-by-allowlisted-function.h b/bindgen-tests/tests/headers/type-referenced-by-allowlisted-function.h similarity index 100% rename from tests/headers/type-referenced-by-allowlisted-function.h rename to bindgen-tests/tests/headers/type-referenced-by-allowlisted-function.h diff --git a/tests/headers/type_alias_empty.hpp b/bindgen-tests/tests/headers/type_alias_empty.hpp similarity index 100% rename from tests/headers/type_alias_empty.hpp rename to bindgen-tests/tests/headers/type_alias_empty.hpp diff --git a/tests/headers/type_alias_partial_template_especialization.hpp b/bindgen-tests/tests/headers/type_alias_partial_template_especialization.hpp similarity index 100% rename from tests/headers/type_alias_partial_template_especialization.hpp rename to bindgen-tests/tests/headers/type_alias_partial_template_especialization.hpp diff --git a/tests/headers/type_alias_template_specialized.hpp b/bindgen-tests/tests/headers/type_alias_template_specialized.hpp similarity index 100% rename from tests/headers/type_alias_template_specialized.hpp rename to bindgen-tests/tests/headers/type_alias_template_specialized.hpp diff --git a/bindgen-tests/tests/headers/typedef-pointer-overlap.h b/bindgen-tests/tests/headers/typedef-pointer-overlap.h new file mode 100644 index 0000000000..8c556c9b38 --- /dev/null +++ b/bindgen-tests/tests/headers/typedef-pointer-overlap.h @@ -0,0 +1,30 @@ +typedef const struct foo { + char inner; +} *foo; + +typedef struct bar { + char inner; +} *bar; + +typedef struct baz *baz; + +typedef union cat { + int standard_issue; +} *cat; + +typedef enum mad { scientist } *mad; + +void takes_foo_ptr(foo); +void takes_foo_struct(struct foo); + +void takes_bar_ptr(bar); +void takes_bar_struct(struct bar); + +void takes_baz_ptr(baz); +void takes_baz_struct(struct baz); + +void takes_cat_ptr(cat); +void takes_cat_union(union cat); + +void takes_mad_ptr(mad); +void takes_mad_enum(enum mad); diff --git a/tests/headers/typedefd-array-as-function-arg.h b/bindgen-tests/tests/headers/typedefd-array-as-function-arg.h similarity index 100% rename from tests/headers/typedefd-array-as-function-arg.h rename to bindgen-tests/tests/headers/typedefd-array-as-function-arg.h diff --git a/tests/headers/typeref.hpp b/bindgen-tests/tests/headers/typeref.hpp similarity index 100% rename from tests/headers/typeref.hpp rename to bindgen-tests/tests/headers/typeref.hpp 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/tests/headers/underscore.hpp b/bindgen-tests/tests/headers/underscore.hpp similarity index 100% rename from tests/headers/underscore.hpp rename to bindgen-tests/tests/headers/underscore.hpp diff --git a/bindgen-tests/tests/headers/union-align.h b/bindgen-tests/tests/headers/union-align.h new file mode 100644 index 0000000000..5ed955f25e --- /dev/null +++ b/bindgen-tests/tests/headers/union-align.h @@ -0,0 +1,8 @@ +union Bar { + unsigned char foo; +} __attribute__ ((__aligned__ (16))); + + +union Baz { + union Bar bar; +}; diff --git a/tests/headers/union-in-ns.hpp b/bindgen-tests/tests/headers/union-in-ns.hpp similarity index 100% rename from tests/headers/union-in-ns.hpp rename to bindgen-tests/tests/headers/union-in-ns.hpp diff --git a/bindgen-tests/tests/headers/union_bitfield.h b/bindgen-tests/tests/headers/union_bitfield.h new file mode 100644 index 0000000000..4592a8973a --- /dev/null +++ b/bindgen-tests/tests/headers/union_bitfield.h @@ -0,0 +1,10 @@ +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq + +union U4 { + unsigned int derp:1; /* 0: 0 4 */ +}; + +union B { + unsigned int foo:31; /* 0: 0 4 */ + unsigned char bar:1; /* 0: 0 1 */ +}; diff --git a/tests/headers/union_dtor.hpp b/bindgen-tests/tests/headers/union_dtor.hpp similarity index 100% rename from tests/headers/union_dtor.hpp rename to bindgen-tests/tests/headers/union_dtor.hpp diff --git a/tests/headers/union_fields.hpp b/bindgen-tests/tests/headers/union_fields.hpp similarity index 100% rename from tests/headers/union_fields.hpp rename to bindgen-tests/tests/headers/union_fields.hpp diff --git a/tests/headers/union_template.hpp b/bindgen-tests/tests/headers/union_template.hpp similarity index 100% rename from tests/headers/union_template.hpp rename to bindgen-tests/tests/headers/union_template.hpp diff --git a/tests/headers/union_with_anon_struct.h b/bindgen-tests/tests/headers/union_with_anon_struct.h similarity index 100% rename from tests/headers/union_with_anon_struct.h rename to bindgen-tests/tests/headers/union_with_anon_struct.h diff --git a/tests/headers/union_with_anon_struct_bitfield.h b/bindgen-tests/tests/headers/union_with_anon_struct_bitfield.h similarity index 100% rename from tests/headers/union_with_anon_struct_bitfield.h rename to bindgen-tests/tests/headers/union_with_anon_struct_bitfield.h diff --git a/tests/headers/union_with_anon_union.h b/bindgen-tests/tests/headers/union_with_anon_union.h similarity index 100% rename from tests/headers/union_with_anon_union.h rename to bindgen-tests/tests/headers/union_with_anon_union.h diff --git a/tests/headers/union_with_anon_unnamed_struct.h b/bindgen-tests/tests/headers/union_with_anon_unnamed_struct.h similarity index 100% rename from tests/headers/union_with_anon_unnamed_struct.h rename to bindgen-tests/tests/headers/union_with_anon_unnamed_struct.h diff --git a/tests/headers/union_with_anon_unnamed_union.h b/bindgen-tests/tests/headers/union_with_anon_unnamed_union.h similarity index 100% rename from tests/headers/union_with_anon_unnamed_union.h rename to bindgen-tests/tests/headers/union_with_anon_unnamed_union.h diff --git a/tests/headers/union_with_big_member.h b/bindgen-tests/tests/headers/union_with_big_member.h similarity index 100% rename from tests/headers/union_with_big_member.h rename to bindgen-tests/tests/headers/union_with_big_member.h diff --git a/tests/headers/union_with_nesting.h b/bindgen-tests/tests/headers/union_with_nesting.h similarity index 100% rename from tests/headers/union_with_nesting.h rename to bindgen-tests/tests/headers/union_with_nesting.h diff --git a/bindgen-tests/tests/headers/union_with_non_copy_member.h b/bindgen-tests/tests/headers/union_with_non_copy_member.h new file mode 100644 index 0000000000..764820a46d --- /dev/null +++ b/bindgen-tests/tests/headers/union_with_non_copy_member.h @@ -0,0 +1,20 @@ +// bindgen-flags: --bindgen-wrapper-union 'WithBindgenGeneratedWrapper' --manually-drop-union 'WithManuallyDrop' --no-copy 'NonCopyType' + +struct NonCopyType { + int foo; +}; + +union WithBindgenGeneratedWrapper { + struct NonCopyType non_copy_type; + int bar; +}; + +union WithManuallyDrop { + struct NonCopyType non_copy_type; + int bar; +}; + +union WithDefaultWrapper { + struct NonCopyType non_copy_type; + int bar; +}; 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/tests/headers/unknown_attr.h b/bindgen-tests/tests/headers/unknown_attr.h similarity index 100% rename from tests/headers/unknown_attr.h rename to bindgen-tests/tests/headers/unknown_attr.h diff --git a/bindgen-tests/tests/headers/unsorted-items.h b/bindgen-tests/tests/headers/unsorted-items.h new file mode 100644 index 0000000000..23962d18d8 --- /dev/null +++ b/bindgen-tests/tests/headers/unsorted-items.h @@ -0,0 +1,15 @@ +int foo(); +typedef int number; +int bar(number x); +struct Point +{ + number x; + number y; +}; +struct Angle +{ + number a; + number b; +}; +int baz(struct Point point); +const number NUMBER = 42; diff --git a/bindgen-tests/tests/headers/use-core.h b/bindgen-tests/tests/headers/use-core.h new file mode 100644 index 0000000000..5ee0ac6f39 --- /dev/null +++ b/bindgen-tests/tests/headers/use-core.h @@ -0,0 +1,13 @@ +// bindgen-flags: --use-core --raw-line '#![cfg(not(target_os="windows"))] 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/tests/headers/using.hpp b/bindgen-tests/tests/headers/using.hpp similarity index 100% rename from tests/headers/using.hpp rename to bindgen-tests/tests/headers/using.hpp 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/tests/headers/var-tracing.hpp b/bindgen-tests/tests/headers/var-tracing.hpp similarity index 100% rename from tests/headers/var-tracing.hpp rename to bindgen-tests/tests/headers/var-tracing.hpp diff --git a/tests/headers/variadic-method.hpp b/bindgen-tests/tests/headers/variadic-method.hpp similarity index 100% rename from tests/headers/variadic-method.hpp rename to bindgen-tests/tests/headers/variadic-method.hpp 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/tests/headers/variadic_template_function.hpp b/bindgen-tests/tests/headers/variadic_template_function.hpp similarity index 100% rename from tests/headers/variadic_template_function.hpp rename to bindgen-tests/tests/headers/variadic_template_function.hpp diff --git a/tests/headers/vector.hpp b/bindgen-tests/tests/headers/vector.hpp similarity index 100% rename from tests/headers/vector.hpp rename to bindgen-tests/tests/headers/vector.hpp diff --git a/tests/headers/virtual_dtor.hpp b/bindgen-tests/tests/headers/virtual_dtor.hpp similarity index 100% rename from tests/headers/virtual_dtor.hpp rename to bindgen-tests/tests/headers/virtual_dtor.hpp diff --git a/bindgen-tests/tests/headers/virtual_inheritance.hpp b/bindgen-tests/tests/headers/virtual_inheritance.hpp new file mode 100644 index 0000000000..b35378d881 --- /dev/null +++ b/bindgen-tests/tests/headers/virtual_inheritance.hpp @@ -0,0 +1,17 @@ +// bindgen-flags: --no-layout-tests +// FIXME: Enable layout tests when #465 is fixed. +class A { + int foo; +}; + +class B: public virtual A { + int bar; +}; + +class C: public virtual A { + int baz; +}; + +class D: public C, public B { + int bazz; +}; diff --git a/tests/headers/virtual_interface.hpp b/bindgen-tests/tests/headers/virtual_interface.hpp similarity index 100% rename from tests/headers/virtual_interface.hpp rename to bindgen-tests/tests/headers/virtual_interface.hpp diff --git a/tests/headers/virtual_overloaded.hpp b/bindgen-tests/tests/headers/virtual_overloaded.hpp similarity index 100% rename from tests/headers/virtual_overloaded.hpp rename to bindgen-tests/tests/headers/virtual_overloaded.hpp diff --git a/bindgen-tests/tests/headers/void_typedef.h b/bindgen-tests/tests/headers/void_typedef.h new file mode 100644 index 0000000000..405cbd0c46 --- /dev/null +++ b/bindgen-tests/tests/headers/void_typedef.h @@ -0,0 +1,9 @@ +typedef void VOID; + +typedef VOID ALSO_VOID; + +void this_api_returns_nothing(void); + +VOID this_api_also_returns_nothing(VOID); + +ALSO_VOID this_other_api_also_returns_nothing(ALSO_VOID); diff --git a/tests/headers/vtable_recursive_sig.hpp b/bindgen-tests/tests/headers/vtable_recursive_sig.hpp similarity index 100% rename from tests/headers/vtable_recursive_sig.hpp rename to bindgen-tests/tests/headers/vtable_recursive_sig.hpp diff --git a/tests/headers/wasm-constructor-returns.hpp b/bindgen-tests/tests/headers/wasm-constructor-returns.hpp similarity index 100% rename from tests/headers/wasm-constructor-returns.hpp rename to bindgen-tests/tests/headers/wasm-constructor-returns.hpp diff --git a/tests/headers/wasm-import-module.h b/bindgen-tests/tests/headers/wasm-import-module.h similarity index 100% rename from tests/headers/wasm-import-module.h rename to bindgen-tests/tests/headers/wasm-import-module.h diff --git a/tests/headers/weird_bitfields.hpp b/bindgen-tests/tests/headers/weird_bitfields.hpp similarity index 100% rename from tests/headers/weird_bitfields.hpp rename to bindgen-tests/tests/headers/weird_bitfields.hpp diff --git a/tests/headers/what_is_going_on.hpp b/bindgen-tests/tests/headers/what_is_going_on.hpp similarity index 100% rename from tests/headers/what_is_going_on.hpp rename to bindgen-tests/tests/headers/what_is_going_on.hpp diff --git a/bindgen-tests/tests/headers/win32-dtors.hpp b/bindgen-tests/tests/headers/win32-dtors.hpp new file mode 100644 index 0000000000..0f0f0e1604 --- /dev/null +++ b/bindgen-tests/tests/headers/win32-dtors.hpp @@ -0,0 +1,29 @@ +// bindgen-flags: -- --target=x86_64-pc-windows-msvc + +struct CppObj { + int x; + + CppObj(int x); + ~CppObj(); +}; + +struct CppObj2 { + int x; + + CppObj2(int x); + virtual ~CppObj2(); +}; + +struct CppObj3 : CppObj2 { + int x; + + CppObj3(int x); + virtual ~CppObj3(); +}; + +struct CppObj4 : CppObj2 { + int x; + + CppObj4(int x); + ~CppObj4(); +}; 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_73.hpp b/bindgen-tests/tests/headers/win32-thiscall_1_73.hpp new file mode 100644 index 0000000000..8c240055b2 --- /dev/null +++ b/bindgen-tests/tests/headers/win32-thiscall_1_73.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --rust-target=1.73 --raw-line '#![cfg(target = "i686-pc-windows-msvc")]' -- --target=i686-pc-windows-msvc + +class Foo { + public: + void test(); + int test2(int var); +}; diff --git a/tests/headers/win32-thiscall_nightly.hpp b/bindgen-tests/tests/headers/win32-thiscall_nightly.hpp similarity index 100% rename from tests/headers/win32-thiscall_nightly.hpp rename to bindgen-tests/tests/headers/win32-thiscall_nightly.hpp diff --git a/bindgen-tests/tests/headers/win32-vectorcall-nightly.h b/bindgen-tests/tests/headers/win32-vectorcall-nightly.h new file mode 100644 index 0000000000..c099bb59a5 --- /dev/null +++ b/bindgen-tests/tests/headers/win32-vectorcall-nightly.h @@ -0,0 +1,3 @@ +// bindgen-flags: --rust-target nightly --raw-line '#![cfg(feature = "nightly")]' --raw-line '#![feature(abi_vectorcall)]' -- --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/tests/headers/with_array_pointers_arguments.h b/bindgen-tests/tests/headers/with_array_pointers_arguments.h similarity index 100% rename from tests/headers/with_array_pointers_arguments.h rename to bindgen-tests/tests/headers/with_array_pointers_arguments.h diff --git a/tests/headers/without_array_pointers_arguments.h b/bindgen-tests/tests/headers/without_array_pointers_arguments.h similarity index 100% rename from tests/headers/without_array_pointers_arguments.h rename to bindgen-tests/tests/headers/without_array_pointers_arguments.h diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h new file mode 100644 index 0000000000..a35e713f2b --- /dev/null +++ b/bindgen-tests/tests/headers/wrap-static-fns.h @@ -0,0 +1,91 @@ +// 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 +// variable only used in bindgen-integration +#ifdef USE_VA_HEADER +#include +#endif + +static inline int foo() { + return 11; +} +static int bar(); +static int bar() { + return 1; +} +inline int baz() { + return 2; +} + +static inline int takes_ptr(int* arg) { + return *arg + 1; +} + +static inline int takes_fn_ptr(int (*f)(int)) { + return f(1); +} + +static inline int takes_fn(int (f)(int)) { + return f(2); +} + +typedef int (func)(int); + +static inline int takes_alias(func f) { + return f(3); +} + +static inline int takes_qualified(const int *const *arg) { + return **arg; +} + +enum foo { + BAR = 0x0, +}; + +static inline enum foo takes_enum(const enum foo f) { + return f; +} + +static inline void nevermore() { + while (1) { } +} + +static inline int takes_fn_with_no_args(int(f)(void)) { + return f(); +} + +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) { + return i; +} + +#ifndef USE_VA_HEADER +static inline int wrap_as_variadic_fn1(int i, __builtin_va_list va) { + return i; +} + +static inline void wrap_as_variadic_fn2(int i, __builtin_va_list va) {} +#else +static inline int wrap_as_variadic_fn1(int i, va_list va) { + int res = 0; + + for (int j = 0; j < i; j++) + res += (int) va_arg(va, int); + + return res; +} + +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.hpp b/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union.hpp new file mode 100644 index 0000000000..34faea5d90 --- /dev/null +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union.hpp @@ -0,0 +1,22 @@ +// bindgen-flags: --wrap-unsafe-ops --no-layout-tests + +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/wrap_unsafe_ops_class.hpp b/bindgen-tests/tests/headers/wrap_unsafe_ops_class.hpp new file mode 100644 index 0000000000..e3d11c571b --- /dev/null +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_class.hpp @@ -0,0 +1,74 @@ +// bindgen-flags: --wrap-unsafe-ops --no-layout-tests + +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/wrap_unsafe_ops_dynamic_loading_simple.h b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h new file mode 100644 index 0000000000..36a638ae2a --- /dev/null +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h @@ -0,0 +1,7 @@ +// bindgen-flags: --dynamic-loading TestLib --wrap-unsafe-ops + +int foo(int x, int y); +int bar(void *x); +int baz(); + +const int FLUX; diff --git a/bindgen-tests/tests/headers/wrap_unsafe_ops_objc_class.h b/bindgen-tests/tests/headers/wrap_unsafe_ops_objc_class.h new file mode 100644 index 0000000000..017795c85d --- /dev/null +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_objc_class.h @@ -0,0 +1,10 @@ +// bindgen-flags: --wrap-unsafe-ops -- -x objective-c +// bindgen-osx-only + +@class Foo; + +Foo* fooVar; + +@interface Foo +-(void)method; +@end diff --git a/tests/headers/zero-size-array-align.h b/bindgen-tests/tests/headers/zero-size-array-align.h similarity index 100% rename from tests/headers/zero-size-array-align.h rename to bindgen-tests/tests/headers/zero-size-array-align.h diff --git a/tests/headers/zero-sized-array.hpp b/bindgen-tests/tests/headers/zero-sized-array.hpp similarity index 100% rename from tests/headers/zero-sized-array.hpp rename to bindgen-tests/tests/headers/zero-sized-array.hpp diff --git a/bindgen-tests/tests/macro_fallback_test_headers/another_header.h b/bindgen-tests/tests/macro_fallback_test_headers/another_header.h new file mode 100644 index 0000000000..b0c40eb43f --- /dev/null +++ b/bindgen-tests/tests/macro_fallback_test_headers/another_header.h @@ -0,0 +1,10 @@ +#ifndef ANOTHER_HEADER_H +#define ANOTHER_HEADER_H + +#include + +#define SHOULD_NOT_GENERATE UINT64_C(~0) +#define MY_CONST UINT32_C(69) +#define NEGATIVE ~0 + +#endif diff --git a/bindgen-tests/tests/macro_fallback_test_headers/one_header.h b/bindgen-tests/tests/macro_fallback_test_headers/one_header.h new file mode 100644 index 0000000000..5058814bba --- /dev/null +++ b/bindgen-tests/tests/macro_fallback_test_headers/one_header.h @@ -0,0 +1,8 @@ +#ifndef ONE_HEADER_H +#define ONE_HEADER_H + +#include + +#define THE_CONST UINT32_C(28) + +#endif 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..eb44e5fc58 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h @@ -0,0 +1,32 @@ +// 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(); 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..a9a9523895 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs @@ -0,0 +1,510 @@ +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, + ), + ), + ]); + 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) + } + }; + + 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 +} diff --git a/bindgen-tests/tests/parse_callbacks/mod.rs b/bindgen-tests/tests/parse_callbacks/mod.rs new file mode 100644 index 0000000000..02d7fe8316 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/mod.rs @@ -0,0 +1,196 @@ +mod add_derives_callback; +mod item_discovery_callback; + +use bindgen::callbacks::*; +use bindgen::FieldVisibilityKind; + +#[derive(Debug)] +pub struct RemovePrefixParseCallback { + pub remove_prefix: Option, +} + +impl RemovePrefixParseCallback { + pub fn new(prefix: &str) -> Self { + RemovePrefixParseCallback { + remove_prefix: Some(prefix.to_string()), + } + } +} + +impl ParseCallbacks for RemovePrefixParseCallback { + fn generated_name_override(&self, item_info: ItemInfo) -> Option { + if let Some(prefix) = &self.remove_prefix { + let (expected_prefix, expected_suffix) = match item_info.kind { + ItemKind::Function => ("function_", "_name"), + ItemKind::Var => ("var_", "_name"), + _ => todo!(), + }; + if let Some(name) = item_info.name.strip_prefix(prefix) { + assert!(name.starts_with(expected_prefix)); + assert!(name.ends_with(expected_suffix)); + return Some(name.to_string()); + } + } + None + } +} + +#[derive(Debug)] +pub struct PrefixLinkNameParseCallback { + pub prefix: Option, +} + +impl PrefixLinkNameParseCallback { + pub fn new(prefix: &str) -> Self { + PrefixLinkNameParseCallback { + prefix: Some(prefix.to_string()), + } + } +} + +impl ParseCallbacks for PrefixLinkNameParseCallback { + fn generated_link_name_override( + &self, + item_info: ItemInfo, + ) -> Option { + self.prefix + .as_deref() + .map(|prefix| format!("{prefix}{}", item_info.name)) + } +} + +#[derive(Debug)] +struct EnumVariantRename; + +impl ParseCallbacks for EnumVariantRename { + fn enum_variant_name( + &self, + _enum_name: Option<&str>, + original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + Some(format!("RENAMED_{original_variant_name}")) + } +} + +#[derive(Debug)] +struct BlocklistedTypeImplementsTrait; + +impl ParseCallbacks for BlocklistedTypeImplementsTrait { + fn blocklisted_type_implements_trait( + &self, + _name: &str, + derive_trait: DeriveTrait, + ) -> Option { + if derive_trait == DeriveTrait::Hash { + Some(ImplementsTrait::No) + } else { + Some(ImplementsTrait::Yes) + } + } +} + +#[derive(Debug)] +struct FieldVisibility { + default: FieldVisibilityKind, +} + +/// 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. +impl ParseCallbacks for FieldVisibility { + fn field_visibility( + &self, + FieldInfo { field_name, .. }: FieldInfo, + ) -> Option { + match (self.default, field_name.starts_with("private_")) { + (FieldVisibilityKind::Private, false) => { + Some(FieldVisibilityKind::Public) + } + (FieldVisibilityKind::Public, true) => { + Some(FieldVisibilityKind::Private) + } + (FieldVisibilityKind::PublicCrate, _) => unimplemented!(), + _ => None, + } + } +} + +#[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; + +impl ParseCallbacks for WrapAsVariadicFn { + fn wrap_as_variadic_fn(&self, name: &str) -> Option { + Some(name.to_owned() + "_wrapped") + } +} + +#[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), + "blocklisted-type-implements-trait" => { + 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-") + { + let lnopc = RemovePrefixParseCallback::new(prefix); + Box::new(lnopc) + } else if let Some(prefix) = + call_back.strip_prefix("prefix-link-name-") + { + let plnpc = PrefixLinkNameParseCallback::new(prefix); + Box::new(plnpc) + } else if let Some(default) = + call_back.strip_prefix("field-visibility-default-") + { + Box::new(FieldVisibility { + default: default.parse().expect( + "unable to parse field-visibility-default callback", + ), + }) + } else { + panic!("Couldn't find name ParseCallbacks: {cb}") + } + } + } +} diff --git a/tests/quickchecking/.gitignore b/bindgen-tests/tests/quickchecking/.gitignore similarity index 100% rename from tests/quickchecking/.gitignore rename to bindgen-tests/tests/quickchecking/.gitignore diff --git a/bindgen-tests/tests/quickchecking/Cargo.toml b/bindgen-tests/tests/quickchecking/Cargo.toml new file mode 100644 index 0000000000..b26ba3b392 --- /dev/null +++ b/bindgen-tests/tests/quickchecking/Cargo.toml @@ -0,0 +1,34 @@ +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.workspace = true +edition.workspace = true + +[lib] +name = "quickchecking" +path = "src/lib.rs" + +[[bin]] +name = "quickchecking" +path = "src/bin.rs" + +[dependencies] +clap.workspace = true +quickcheck.workspace = true +tempfile.workspace = true + +[features] +# No features by default. +default = [] + +# Enable the generation of code that allows for zero sized arrays as struct +# fields. Until issues #684 and #1153 are resolved this can result in failing tests. +zero-sized-arrays = [] + +# Enable the generation of code that allows for long double types as struct +# fields. Until issue #550 is resolved this can result in failing tests. +long-doubles = [] diff --git a/bindgen-tests/tests/quickchecking/README.md b/bindgen-tests/tests/quickchecking/README.md new file mode 100644 index 0000000000..03aa0f2313 --- /dev/null +++ b/bindgen-tests/tests/quickchecking/README.md @@ -0,0 +1,40 @@ +# Property tests for `bindgen` with `quickchecking` + +`quickchecking` generates random C headers to test `bindgen` +using the [`quickcheck`] property testing crate. When testing +`bindgen` with `quickchecking`, the generated header files are passed to +`bindgen`'s `csmith-fuzzing/predicate.py` script. If that script fails, +`quickchecking` panics, and you can report an issue containing the test case! + + + + + +- [Prerequisites](#prerequisites) +- [Running](#running) + + + +## Prerequisites + +Requires `python3` to be in `$PATH`. + +Many systems have `python3` by default but if your OS doesn't, its package +manager may make it available: + +``` +$ sudo apt install python3 +$ brew install python3 +$ # Etc... +``` + +## Running + +Run `quickchecking` binary to generate and test fuzzed C headers with +`cargo run`. Additional configuration is exposed through the binary's CLI. + +``` +$ cargo run --bin=quickchecking -- -h +``` + +[`quickcheck`]: https://github.com/BurntSushi/quickcheck diff --git a/bindgen-tests/tests/quickchecking/src/bin.rs b/bindgen-tests/tests/quickchecking/src/bin.rs new file mode 100644 index 0000000000..3072bc7b46 --- /dev/null +++ b/bindgen-tests/tests/quickchecking/src/bin.rs @@ -0,0 +1,110 @@ +//! An application to run property tests for `bindgen` with _fuzzed_ C headers +//! using `quickcheck` +//! +//! ## Usage +//! +//! Print help +//! ```bash +//! $ cargo run --bin=quickchecking -- -h +//! ``` +//! +//! Run with default values +//! ```bash +//! $ cargo run --bin=quickchecking +//! ``` +//! +#![deny(missing_docs)] + +use clap::{Arg, ArgAction, Command}; +use std::path::PathBuf; + +// Parse CLI argument input for generation range. +fn parse_generate_range(v: &str) -> Result { + match v.parse::() { + Ok(v) => Ok(v), + Err(_) => Err(String::from( + "Generate range could not be converted to a usize.", + )), + } +} + +// Parse CLI argument input for tests count. +fn parse_tests_count(v: &str) -> Result { + match v.parse::() { + Ok(v) => Ok(v), + Err(_) => Err(String::from( + "Tests count could not be converted to a usize.", + )), + } +} + +// Parse CLI argument input for fuzzed headers output path. +fn parse_path(v: &str) -> Result { + let path = PathBuf::from(v); + if path.is_dir() { + Ok(path) + } else { + Err(String::from("Provided directory path does not exist.")) + } +} + +fn main() { + let matches = Command::new("quickchecking") + .version("0.2.0") + .about( + "Bindgen property tests with quickcheck. \ + Generate random valid C code and pass it to the \ + csmith/predicate.py script", + ) + .arg( + Arg::new("path") + .short('p') + .long("path") + .value_name("PATH") + .help( + "Optional. Preserve generated headers for inspection, \ + provide directory path for header output. [default: None] ", + ) + .action(ArgAction::Set) + .value_parser(parse_path), + ) + .arg( + Arg::new("range") + .short('r') + .long("range") + .value_name("RANGE") + .help( + "Sets the range quickcheck uses during generation. \ + Corresponds to things like arbitrary usize and \ + arbitrary vector length. This number doesn't have \ + to grow much for execution time to increase \ + significantly.", + ) + .action(ArgAction::Set) + .default_value("32") + .value_parser(parse_generate_range), + ) + .arg( + Arg::new("count") + .short('c') + .long("count") + .value_name("COUNT") + .help( + "Count / number of tests to run. Running a fuzzed \ + header through the predicate.py script can take a \ + long time, especially if the generation range is \ + large. Increase this number if you're willing to \ + wait a while.", + ) + .action(ArgAction::Set) + .default_value("2") + .value_parser(parse_tests_count), + ) + .get_matches(); + + let output_path = matches.get_one::("path").map(PathBuf::as_path); + let generate_range = *matches.get_one::("range").unwrap(); + let tests = *matches.get_one::("count").unwrap(); + + 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 new file mode 100644 index 0000000000..176636f66f --- /dev/null +++ b/bindgen-tests/tests/quickchecking/src/fuzzers.rs @@ -0,0 +1,633 @@ +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 +/// primitive types as well as `void*`. +#[derive(Debug, Clone)] +pub struct BaseTypeC { + /// String representation of C type. + pub def: String, +} + +/// `TypeQualifierC` is used in generation of C headers to represent qualifiers +/// such as `const`. +#[derive(Debug, Clone)] +pub struct TypeQualifierC { + /// String representation of C type qualifier. + pub def: String, +} + +/// `PointerLevelC` is used in generation of C headers to represent number of +/// `*` for pointer types. +#[derive(Debug, Clone)] +pub struct PointerLevelC { + /// String representation of C declaration's pointer level. + pub def: String, +} + +/// `ArrayDimensionC` is used in generation of C headers to represent number of +/// `[]` used to define array types. +#[derive(Debug, Clone)] +pub struct ArrayDimensionC { + /// String representation of C declaration's array dimension. + pub def: String, +} + +/// `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)] +pub struct BasicTypeDeclarationC { + /// The declaration's base type, i.e. `int`. + pub type_name: BaseTypeC, + /// The declaration's type qualifier, i.e. `const`. + pub type_qualifier: TypeQualifierC, + /// The declaration's pointer level, i.e. `***`. + pub pointer_level: PointerLevelC, + /// The declaration's array dimension, i.e. [][][]. + pub array_dimension: ArrayDimensionC, + /// The declaration's identifier, i.e. `ident_N`. + pub ident_id: String, +} + +/// `StructDeclarationC` is used in generation of C headers to represent the +/// definition of a struct type. +#[derive(Debug, Clone)] +pub struct StructDeclarationC { + /// The declaration's fields. + pub fields: DeclarationListC, + /// The declaration's array dimension, i.e. [][][]. + pub array_dimension: ArrayDimensionC, + /// The declaration's identifier, i.e. `struct_N`. + pub ident_id: String, +} + +/// `UnionDeclarationC` is used in generation of C headers to represent the +/// definition of a union type. +#[derive(Debug, Clone)] +pub struct UnionDeclarationC { + /// The declaration's fields. + pub fields: DeclarationListC, + /// The declaration's array dimension, i.e. [][][]. + pub array_dimension: ArrayDimensionC, + /// The declaration's identifier, i.e. `union_N`. + pub ident_id: String, +} + +/// `FunctionPointerDeclarationC` is used in generation of C headers to represent +/// the definition of a function pointer type. +#[derive(Debug, Clone)] +pub struct FunctionPointerDeclarationC { + /// The function's type qualifier, i.e. `const`. + pub type_qualifier: TypeQualifierC, + /// The function's return type, i.e. `int`. + pub type_name: BaseTypeC, + /// The function's pointer level, i.e. `***`. + pub pointer_level: PointerLevelC, + /// The function's parameters. + pub params: ParameterListC, + /// The declaration's identifier, i.e. `func_ptr_N`. + pub ident_id: String, +} + +/// `FunctionPrototypeC` is used in generation of C headers to represent the +/// definition of a function prototype. +#[derive(Debug, Clone)] +pub struct FunctionPrototypeC { + /// The function's type qualifier, i.e. `const`. + pub type_qualifier: TypeQualifierC, + /// The function's return type, i.e. `int`. + pub type_name: BaseTypeC, + /// The function's pointer level, i.e. `***`. + pub pointer_level: PointerLevelC, + /// The function's parameters. + pub params: ParameterListC, + /// The prototype's identifier, i.e. `func_N`. + pub ident_id: String, +} + +/// `ParameterC` is used in generation of C headers to represent the +/// definition function parameters. +#[derive(Debug, Clone)] +pub struct ParameterC { + /// The parameter's type qualifier, i.e. `const`. + pub type_qualifier: TypeQualifierC, + /// The parameter's base type, i.e. `int`. + pub type_name: BaseTypeC, + /// The parameter's pointer level, i.e. `***`. + pub pointer_level: PointerLevelC, +} + +/// `ParameterListC` is used in generation of C headers to represent a list of +/// definitions of function parameters. +#[derive(Debug, Clone)] +pub struct ParameterListC { + /// Parameters that define a C function signature. + pub params: Vec, +} + +/// `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 { + /// Function prototype declaration kind. + FunctionDecl(FunctionPrototypeC), + /// Function pointer declaration kind. + FunctionPtrDecl(FunctionPointerDeclarationC), + /// Struct declaration kind. + StructDecl(StructDeclarationC), + /// Union declaration kind. + UnionDecl(UnionDeclarationC), + /// Basic type declaration kind. + VariableDecl(BasicTypeDeclarationC), +} + +/// `DeclarationListC` is used in generation of C headers to represent a list of +/// declarations. +#[derive(Debug, Clone)] +pub struct DeclarationListC { + /// Grouping of C declarations. + pub decls: Vec, +} + +/// `HeaderC` is used in generation of C headers to represent a collection of +/// declarations. +#[derive(Clone)] +pub struct HeaderC { + /// The header's declarations. + pub def: DeclarationListC, +} + +/// `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` +/// identifiers unique. +impl MakeUnique for DeclarationC { + fn make_unique(&mut self, stamp: usize) { + match *self { + DeclarationC::FunctionDecl(ref mut d) => d.make_unique(stamp), + DeclarationC::FunctionPtrDecl(ref mut d) => d.make_unique(stamp), + DeclarationC::StructDecl(ref mut d) => d.make_unique(stamp), + DeclarationC::UnionDecl(ref mut d) => d.make_unique(stamp), + DeclarationC::VariableDecl(ref mut d) => d.make_unique(stamp), + } + } +} + +/// A qucickcheck trait for describing how `DeclarationC` types can be +/// randomly generated and shrunk. +impl Arbitrary for DeclarationC { + fn arbitrary(g: &mut Gen) -> DeclarationC { + match gen_range(g, 0, 5) { + 0 => DeclarationC::FunctionDecl(FunctionPrototypeC::arbitrary(g)), + 1 => DeclarationC::FunctionPtrDecl( + FunctionPointerDeclarationC::arbitrary(g), + ), + 2 => DeclarationC::StructDecl(StructDeclarationC::arbitrary(g)), + 3 => DeclarationC::UnionDecl(UnionDeclarationC::arbitrary(g)), + 4 => { + DeclarationC::VariableDecl(BasicTypeDeclarationC::arbitrary(g)) + } + _ => unreachable!(), + } + } +} + +/// 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}"), + } + } +} + +/// A qucickcheck trait for describing how `DeclarationListC` types can be +/// randomly generated and shrunk. +impl Arbitrary for DeclarationListC { + fn arbitrary(g: &mut Gen) -> DeclarationListC { + DeclarationListC { + decls: Arbitrary::arbitrary(g), + } + } +} + +/// Enables to string and format for `DeclarationListC` types. +impl fmt::Display for DeclarationListC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for decl in &self.decls { + write!(f, "{decl}")?; + } + Ok(()) + } +} + +/// A quickcheck trait for describing how `BaseTypeC` types can be +/// randomly generated and shrunk. +impl Arbitrary for BaseTypeC { + fn arbitrary(g: &mut Gen) -> BaseTypeC { + // Special case `long double` until issue #550 is resolved. + let base_type = vec![ + "char", + "signed char", + "unsigned char", + "short", + "short int", + "signed short", + "signed short int", + "unsigned short", + "unsigned short int", + "int", + "signed", + "signed int", + "unsigned", + "unsigned int", + "long", + "long int", + "signed long", + "signed long int", + "unsigned long", + "unsigned long int", + "long long", + "long long int", + "signed long long", + "signed long long int", + "unsigned long long", + "unsigned long long int", + "float", + "double", + #[cfg(feature = "long-doubles")] + "long double", + "void*", + ]; + BaseTypeC { + def: String::from(*g.choose(&base_type).unwrap()), + } + } +} + +/// 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 +/// randomly generated and shrunk. +impl Arbitrary for TypeQualifierC { + fn arbitrary(g: &mut Gen) -> TypeQualifierC { + let qualifier = vec!["const", ""]; + TypeQualifierC { + def: String::from(*g.choose(&qualifier).unwrap()), + } + } +} + +/// 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 +/// randomly generated and shrunk. +impl Arbitrary for PointerLevelC { + fn arbitrary(g: &mut Gen) -> PointerLevelC { + PointerLevelC { + // 16 is an arbitrary "not too big" number for capping pointer level. + def: (0..gen_range(g, 0, 16)).map(|_| "*").collect::(), + } + } +} + +/// 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 +/// randomly generated and shrunk. +impl Arbitrary for ArrayDimensionC { + fn arbitrary(g: &mut Gen) -> ArrayDimensionC { + // Keep these small, clang complains when they get too big. + let dimensions = gen_range(g, 0, 5); + let mut def = String::new(); + + let lower_bound = u64::from(cfg!(feature = "zero-sized-arrays")); + + for _ in 1..dimensions { + // 16 is an arbitrary "not too big" number for capping array size. + let _ = write!(def, "[{}]", gen_range(g, lower_bound, 16)); + } + ArrayDimensionC { def } + } +} + +/// 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` +/// identifiers unique. +impl MakeUnique for BasicTypeDeclarationC { + fn make_unique(&mut self, stamp: usize) { + let _ = write!(self.ident_id, "_{stamp}"); + } +} + +/// A qucickcheck trait for describing how `BasicTypeDeclarationC` types can be +/// randomly generated and shrunk. +impl Arbitrary for BasicTypeDeclarationC { + fn arbitrary(g: &mut Gen) -> BasicTypeDeclarationC { + BasicTypeDeclarationC { + type_qualifier: Arbitrary::arbitrary(g), + type_name: Arbitrary::arbitrary(g), + pointer_level: Arbitrary::arbitrary(g), + array_dimension: Arbitrary::arbitrary(g), + ident_id: format!("{}", usize::arbitrary(g)), + } + } +} + +/// Enables to string and format for `BasicTypeDeclarationC` types. +impl fmt::Display for BasicTypeDeclarationC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{} {} {} ident_{}{};", + self.type_qualifier, + self.type_name, + self.pointer_level, + self.ident_id, + self.array_dimension + ) + } +} + +/// `MakeUnique` is used in generation of C headers to make `StructDeclarationC` +/// identifiers unique. +impl MakeUnique for StructDeclarationC { + fn make_unique(&mut self, stamp: usize) { + let _ = write!(self.ident_id, "_{stamp}"); + } +} + +/// A qucickcheck trait for describing how `StructDeclarationC` types can be +/// randomly generated and shrunk. +impl Arbitrary for StructDeclarationC { + fn arbitrary(g: &mut Gen) -> StructDeclarationC { + // Reduce generator size as a method of putting a bound on recursion. + // When size < 1 the empty list is generated. + let reduced_size: usize = (g.size() / 2) + 1; + let mut decl_list: DeclarationListC = + Arbitrary::arbitrary(&mut Gen::new(reduced_size)); + let mut fields: DeclarationListC = DeclarationListC { decls: vec![] }; + + for (i, decl) in decl_list.decls.iter_mut().enumerate() { + match *decl { + DeclarationC::FunctionDecl(_) => {} + ref mut decl => { + decl.make_unique(i); + fields.decls.push(decl.clone()); + } + } + } + + StructDeclarationC { + fields, + ident_id: format!("{}", usize::arbitrary(g)), + array_dimension: Arbitrary::arbitrary(g), + } + } +} + +/// Enables to string and format for `StructDeclarationC` types. +impl fmt::Display for StructDeclarationC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "struct {{ {} }} struct_{}{};", + self.fields, self.ident_id, self.array_dimension + ) + } +} + +/// `MakeUnique` is used in generation of C headers to make `UnionDeclarationC` +/// identifiers unique. +impl MakeUnique for UnionDeclarationC { + fn make_unique(&mut self, stamp: usize) { + let _ = write!(self.ident_id, "_{stamp}"); + } +} + +/// A qucickcheck trait for describing how `UnionDeclarationC` types can be +/// randomly generated and shrunk. +impl Arbitrary for UnionDeclarationC { + fn arbitrary(g: &mut Gen) -> UnionDeclarationC { + // Reduce generator size as a method of putting a bound on recursion. + // When size < 1 the empty list is generated. + let reduced_size: usize = (g.size() / 2) + 1; + let mut decl_list: DeclarationListC = + Arbitrary::arbitrary(&mut Gen::new(reduced_size)); + let mut fields: DeclarationListC = DeclarationListC { decls: vec![] }; + + for (i, decl) in decl_list.decls.iter_mut().enumerate() { + match *decl { + DeclarationC::FunctionDecl(_) => {} + ref mut decl => { + decl.make_unique(i); + fields.decls.push(decl.clone()); + } + } + } + + UnionDeclarationC { + fields, + ident_id: format!("{}", usize::arbitrary(g)), + array_dimension: Arbitrary::arbitrary(g), + } + } +} + +/// Enables to string and format for `UnionDeclarationC` types. +impl fmt::Display for UnionDeclarationC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "union {{ {} }} union_{}{};", + self.fields, self.ident_id, self.array_dimension + ) + } +} + +/// `MakeUnique` is used in generation of C headers to make +/// `FunctionPointerDeclarationC` identifiers unique. +impl MakeUnique for FunctionPointerDeclarationC { + fn make_unique(&mut self, stamp: usize) { + let _ = write!(self.ident_id, "_{stamp}"); + } +} + +/// A qucickcheck trait for describing how `FunctionPointerDeclarationC` types can +/// be randomly generated and shrunk. +impl Arbitrary for FunctionPointerDeclarationC { + fn arbitrary(g: &mut Gen) -> FunctionPointerDeclarationC { + FunctionPointerDeclarationC { + type_qualifier: Arbitrary::arbitrary(g), + type_name: Arbitrary::arbitrary(g), + pointer_level: Arbitrary::arbitrary(g), + params: Arbitrary::arbitrary(g), + ident_id: format!("{}", usize::arbitrary(g)), + } + } +} + +/// Enables to string and format for `FunctionPointerDeclarationC` types. +impl fmt::Display for FunctionPointerDeclarationC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{} {} {} (*func_ptr_{})({});", + self.type_qualifier, + self.type_name, + self.pointer_level, + self.ident_id, + self.params + ) + } +} + +/// `MakeUnique` is used in generation of C headers to make `FunctionPrototypeC` +/// identifiers unique. +impl MakeUnique for FunctionPrototypeC { + fn make_unique(&mut self, stamp: usize) { + let _ = write!(self.ident_id, "_{stamp}"); + } +} + +/// A qucickcheck trait for describing how `FunctionPrototypeC` types can be +/// randomly generated and shrunk. +impl Arbitrary for FunctionPrototypeC { + fn arbitrary(g: &mut Gen) -> FunctionPrototypeC { + FunctionPrototypeC { + type_qualifier: Arbitrary::arbitrary(g), + type_name: Arbitrary::arbitrary(g), + pointer_level: Arbitrary::arbitrary(g), + params: Arbitrary::arbitrary(g), + ident_id: format!("{}", usize::arbitrary(g)), + } + } +} + +/// Enables to string and format for `FunctionPrototypeC` types. +impl fmt::Display for FunctionPrototypeC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{} {} {} func_{}({});", + self.type_qualifier, + self.type_name, + self.pointer_level, + self.ident_id, + self.params + ) + } +} + +/// A qucickcheck trait for describing how `ParameterC` types can be +/// randomly generated and shrunk. +impl Arbitrary for ParameterC { + fn arbitrary(g: &mut Gen) -> ParameterC { + ParameterC { + type_qualifier: Arbitrary::arbitrary(g), + type_name: Arbitrary::arbitrary(g), + pointer_level: Arbitrary::arbitrary(g), + } + } +} + +/// Enables to string and format for `ParameterC` types. +impl fmt::Display for ParameterC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{} {} {}", + self.type_qualifier, self.type_name, self.pointer_level + ) + } +} + +/// A qucickcheck trait for describing how `ParameterListC` types can be +/// randomly generated and shrunk. +impl Arbitrary for ParameterListC { + fn arbitrary(g: &mut Gen) -> ParameterListC { + ParameterListC { + params: Arbitrary::arbitrary(g), + } + } +} + +/// Enables to string and format for `ParameterListC` types. +impl fmt::Display for ParameterListC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for (i, p) in self.params.iter().enumerate() { + match i { + 0 => write!(f, "{p}")?, + _ => write!(f, ",{p}")?, + } + } + Ok(()) + } +} + +/// A qucickcheck trait for describing how `HeaderC` types can be +/// randomly generated and shrunk. +impl Arbitrary for HeaderC { + fn arbitrary(g: &mut Gen) -> HeaderC { + let mut decl_list: DeclarationListC = Arbitrary::arbitrary(g); + for (i, decl) in decl_list.decls.iter_mut().enumerate() { + decl.make_unique(i); + } + HeaderC { def: decl_list } + } +} + +/// Enables to string and format for `HeaderC` types. +impl fmt::Display for HeaderC { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for decl in &self.def.decls { + write!(f, "{decl}")?; + } + Ok(()) + } +} + +/// Use Display trait for Debug so that any failing property tests report +/// 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}") + } +} + +/// FIXME: is this actually uniform? +fn gen_range(gen: &mut Gen, lo: u64, hi: u64) -> u64 { + let len = hi - lo; + (u64::arbitrary(gen) % len) + lo +} diff --git a/bindgen-tests/tests/quickchecking/src/lib.rs b/bindgen-tests/tests/quickchecking/src/lib.rs new file mode 100644 index 0000000000..7567a3bea6 --- /dev/null +++ b/bindgen-tests/tests/quickchecking/src/lib.rs @@ -0,0 +1,108 @@ +//! A library to generate __fuzzed__ C headers for use with `quickcheck` +//! +//! ## Example +//! +//! ```rust +//! use quickcheck::{Arbitrary, Gen}; +//! use quickchecking::fuzzers; +//! +//! 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)] + +use quickcheck::{Gen, QuickCheck, TestResult}; +use std::error::Error; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output}; +use std::sync::Mutex; +use tempfile::Builder; + +/// Contains definitions of and impls for types used to fuzz C declarations. +pub mod fuzzers; + +// Global singleton, manages context across tests. For now that context is +// only the output_path for inspecting fuzzed headers (if specified). +struct Context { + output_path: Option, +} + +// Initialize global context. +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, +) -> Result> { + let dir = Builder::new().prefix("bindgen_prop").tempdir()?; + let header_path = dir.path().join("prop_test.h"); + + let mut header_file = File::create(&header_path)?; + header_file.write_all(header.to_string().as_bytes())?; + header_file.sync_all()?; + + let header_path_string = header_path + .into_os_string() + .into_string() + .map_err(|_| "error converting path into String")?; + + let mut predicate_script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + predicate_script_path.push("../../csmith-fuzzing/predicate.py"); + + let predicate_script_path_string = predicate_script_path + .into_os_string() + .into_string() + .map_err(|_| "error converting path into String")?; + + // Copy generated temp files to output_path directory for inspection. + // If `None`, output path not specified, don't copy. + if let Some(ref path) = CONTEXT.lock().unwrap().output_path { + Command::new("cp") + .arg("-a") + .arg(dir.path().to_str().unwrap()) + .arg(path) + .output()?; + } + + Ok(Command::new(predicate_script_path_string) + .arg(&header_path_string) + .output()?) +} + +// 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) { + Ok(o) => TestResult::from_bool(o.status.success()), + Err(e) => { + println!("{e:?}"); + TestResult::from_bool(false) + } + } +} + +/// Instantiate a Quickcheck object and use it to run property tests using +/// fuzzed C headers generated with types defined in the `fuzzers` module. +/// Success/Failure is dictated by the result of passing the fuzzed headers +/// to the `csmith-fuzzing/predicate.py` script. +pub fn test_bindgen( + generate_range: usize, + tests: u64, + output_path: Option<&Path>, +) { + if let Some(path) = output_path { + CONTEXT.lock().unwrap().output_path = Some(path.display().to_string()); + } + + QuickCheck::new() + .tests(tests) + .gen(Gen::new(generate_range)) + .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult); +} diff --git a/bindgen-tests/tests/quickchecking/tests/fuzzed-c-headers.rs b/bindgen-tests/tests/quickchecking/tests/fuzzed-c-headers.rs new file mode 100644 index 0000000000..0735a70c47 --- /dev/null +++ b/bindgen-tests/tests/quickchecking/tests/fuzzed-c-headers.rs @@ -0,0 +1,90 @@ +use quickcheck::{Arbitrary, Gen}; +use quickchecking::fuzzers::{ + ArrayDimensionC, BaseTypeC, BasicTypeDeclarationC, DeclarationC, + DeclarationListC, FunctionPointerDeclarationC, FunctionPrototypeC, HeaderC, + ParameterC, ParameterListC, PointerLevelC, StructDeclarationC, + TypeQualifierC, UnionDeclarationC, +}; +#[test] +fn test_declaraion_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: DeclarationC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_declaraion_list_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: DeclarationListC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_base_type_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: BaseTypeC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_type_qualifier_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: TypeQualifierC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_pointer_level_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: PointerLevelC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_array_dimension_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: ArrayDimensionC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_basic_type_declaration_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: BasicTypeDeclarationC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_struct_declaration_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: StructDeclarationC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_union_declaration_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: UnionDeclarationC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_function_pointer_declaration_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: FunctionPointerDeclarationC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_function_prototype_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: FunctionPrototypeC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_parameter_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: ParameterC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_parameter_list_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: ParameterListC = Arbitrary::arbitrary(gen); +} + +#[test] +fn test_header_c_does_not_panic() { + let gen = &mut Gen::new(50); + let _: HeaderC = Arbitrary::arbitrary(gen); +} diff --git a/tests/rustfmt.toml b/bindgen-tests/tests/rustfmt.toml similarity index 100% rename from tests/rustfmt.toml rename to bindgen-tests/tests/rustfmt.toml diff --git a/tests/stylo.hpp b/bindgen-tests/tests/stylo.hpp similarity index 100% rename from tests/stylo.hpp rename to bindgen-tests/tests/stylo.hpp diff --git a/tests/stylo_sanity.rs b/bindgen-tests/tests/stylo_sanity.rs similarity index 99% rename from tests/stylo_sanity.rs rename to bindgen-tests/tests/stylo_sanity.rs index f44f12878d..7b94e2989e 100755 --- a/tests/stylo_sanity.rs +++ b/bindgen-tests/tests/stylo_sanity.rs @@ -1,7 +1,3 @@ -// Don't want to copy that nasty `cfg` below... -#[allow(unused_extern_crates)] -extern crate bindgen; - /// A sanity test that we can generate bindings for Stylo. /// /// We don't assert on expected output because its just too big. The output will @@ -14,11 +10,13 @@ extern crate bindgen; /// how long bindings generation takes for Stylo. Stylo bindings generation /// takes too long to be a proper `#[bench]`. #[test] -#[cfg(not(any(debug_assertions, feature = "testing_only_extra_assertions",)))] +#[cfg(not(any( + debug_assertions, + feature = "__testing_only_extra_assertions", +)))] #[cfg(any( - feature = "testing_only_libclang_4", - feature = "testing_only_libclang_5", - feature = "testing_only_libclang_9" + feature = "__testing_only_libclang_9", + feature = "__testing_only_libclang_16" ))] fn sanity_check_can_generate_stylo_bindings() { use std::time::Instant; diff --git a/tests/test-one.sh b/bindgen-tests/tests/test-one.sh similarity index 87% rename from tests/test-one.sh rename to bindgen-tests/tests/test-one.sh index 91da55b1a5..5ab6e9a468 100755 --- a/tests/test-one.sh +++ b/bindgen-tests/tests/test-one.sh @@ -45,19 +45,18 @@ TEST_BINDINGS_BINARY=$(mktemp -t bindings.XXXXXX) FLAGS="$(grep "// bindgen-flags: " "$TEST" || echo)" FLAGS="${FLAGS/\/\/ bindgen\-flags:/}" # Prepend the default flags added in test.rs's `create_bindgen_builder`. -FLAGS="--rustfmt-bindings --with-derive-default --raw-line '' --raw-line '#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]' --raw-line '' $FLAGS" +FLAGS="--with-derive-default --raw-line '' --raw-line '#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]' --raw-line '' $FLAGS" -eval ./target/debug/bindgen \ +eval ../target/debug/bindgen \ "\"$TEST\"" \ --emit-ir \ --emit-ir-graphviz ir.dot \ --emit-clang-ast \ + --formatter prettyplease \ -o "\"$BINDINGS\"" \ $FLAGS -rustup run nightly rustfmt "$BINDINGS" || true - dot -Tpng ir.dot -o ir.png echo @@ -80,8 +79,6 @@ EXPECTED=${TEST/headers/expectations\/tests} EXPECTED=${EXPECTED/.hpp/.rs} EXPECTED=${EXPECTED/.h/.rs} -rustup run nightly rustfmt "$EXPECTED" || true - # Don't exit early if there is a diff. diff -U8 "$EXPECTED" "$BINDINGS" || true diff --git a/bindgen-tests/tests/tests.rs b/bindgen-tests/tests/tests.rs new file mode 100644 index 0000000000..6e3c358d3e --- /dev/null +++ b/bindgen-tests/tests/tests.rs @@ -0,0 +1,776 @@ +use bindgen::{clang_version, Builder}; +use owo_colors::{OwoColorize, Style}; +use similar::{ChangeTag, TextDiff}; +use std::env; +use std::fmt; +use std::fs; +use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Write}; +use std::path::{Path, PathBuf}; + +use bindgen::builder_from_flags; + +mod parse_callbacks; + +// Format the given source string. It can fail if the source string does not contain syntactically +// valid Rust. +fn format_code>(source: S) -> syn::Result { + use prettyplease::unparse; + use syn::{parse_str, File}; + + let file = parse_str::(source.as_ref())?; + Ok(unparse(&file)) +} + +fn should_overwrite_expected() -> bool { + if let Some(var) = env::var_os("BINDGEN_OVERWRITE_EXPECTED") { + if var == "1" { + return true; + } + assert!( + var == "0" || var.is_empty(), + "Invalid value of BINDGEN_OVERWRITE_EXPECTED" + ); + } + false +} + +fn error_diff_mismatch( + actual: &str, + expected: &str, + header: Option<&Path>, + filename: &Path, +) -> Result<(), Error> { + println!("diff expected generated"); + println!("--- expected: {}", filename.display()); + if let Some(header) = header { + println!("+++ generated from: {}", header.display()); + } + + show_diff(expected, actual); + + if should_overwrite_expected() { + // Overwrite the expectation with actual output. + let mut expectation_file = fs::File::create(filename)?; + expectation_file.write_all(actual.as_bytes())?; + } + + if let Some(var) = env::var_os("BINDGEN_TESTS_DIFFTOOL") { + //usecase: var = "meld" -> You can hand check differences + 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); + let mut actual_result_file = fs::File::create(&actual_result_path)?; + actual_result_file.write_all(actual.as_bytes())?; + std::process::Command::new(var) + .args([filename, &actual_result_path]) + .output()?; + } + + Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation or with BINDGEN_TESTS_DIFFTOOL=meld to do this manually.")) +} + +struct Line(Option); + +impl fmt::Display for Line { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.0 { + None => write!(f, " "), + Some(idx) => write!(f, "{:<4}", idx + 1), + } + } +} + +fn show_diff(old: &str, new: &str) { + let diff = TextDiff::from_lines(old, new); + for (count, group) in diff.grouped_ops(3).iter().enumerate() { + if count > 0 { + let message = format!("(chunk {count}/n)"); + println!("{}", message.cyan().dimmed()); + } + for diff_op in group { + for change in diff.iter_inline_changes(diff_op) { + let (sign, color) = match change.tag() { + ChangeTag::Delete => ("-", Style::new().red()), + ChangeTag::Insert => ("+", Style::new().green()), + ChangeTag::Equal => (" ", Style::new()), + }; + print!( + "{}{}| {}", + Line(change.old_index()).style(color).dimmed(), + Line(change.new_index()).style(color).dimmed(), + sign.style(color).bold(), + ); + for (emphasized, text) in change.iter_strings_lossy() { + if emphasized { + print!("{}", text.style(color).underline()); + } else { + print!("{}", text.style(color)); + } + } + if change.missing_newline() { + println!(); + } + } + } + } +} + +fn compare_generated_header( + header: &Path, + builder: BuilderState, + check_roundtrip: bool, +) -> Result<(), Error> { + let file_name = header.file_name().ok_or_else(|| { + Error::new(ErrorKind::Other, "compare_generated_header expects a file") + })?; + + let mut expectation = PathBuf::from(header); + expectation.pop(); + expectation.pop(); + expectation.push("expectations"); + expectation.push("tests"); + + let mut looked_at = vec![]; + let mut expectation_file; + + // Try more specific expectations first. + { + let mut expectation = expectation.clone(); + + if cfg!(feature = "__testing_only_libclang_16") { + expectation.push("libclang-16"); + } else if cfg!(feature = "__testing_only_libclang_9") { + expectation.push("libclang-9"); + } else { + match clang_version().parsed { + None => expectation.push("libclang-16"), + Some(version) => { + let (maj, min) = version; + let version_str = if maj >= 16 { + "16".to_owned() + } else if maj >= 9 { + "9".to_owned() + } else { + format!("{maj}.{min}") + }; + expectation.push(format!("libclang-{version_str}")); + } + } + } + + expectation.push(file_name); + expectation.set_extension("rs"); + expectation_file = fs::File::open(&expectation).ok(); + looked_at.push(expectation); + } + + // Try the default path otherwise. + if expectation_file.is_none() { + expectation.push(file_name); + expectation.set_extension("rs"); + expectation_file = fs::File::open(&expectation).ok(); + looked_at.push(expectation.clone()); + } + + let mut expected = String::new(); + match expectation_file { + Some(f) => { + BufReader::new(f).read_to_string(&mut expected)?; + } + None => panic!( + "missing test expectation file and/or '__testing_only_libclang_$VERSION' \ + feature for header '{}'; looking for expectation file at '{looked_at:?}'", + header.display(), + ), + } + + let (builder, roundtrip_builder) = builder.into_builder(check_roundtrip)?; + + // We skip the generate() error here so we get a full diff below + let actual = match builder.generate() { + Ok(bindings) => format_code(bindings.to_string()).map_err(|err| { + Error::new( + ErrorKind::Other, + format!("Cannot parse the generated bindings: {err}"), + ) + })?, + Err(_) => "/* error generating bindings */\n".into(), + }; + + if actual.is_empty() { + return Err(Error::new( + ErrorKind::Other, + "Something's gone really wrong!", + )); + } + if actual != expected { + return error_diff_mismatch( + &actual, + &expected, + Some(header), + looked_at.last().unwrap(), + ); + } + + if let Some(roundtrip_builder) = roundtrip_builder { + 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}"))); + } + } + + Ok(()) +} + +fn builder() -> Builder { + #[cfg(feature = "logging")] + let _ = env_logger::try_init(); + + bindgen::builder().disable_header_comment() +} + +struct BuilderState { + builder: Builder, + parse_callbacks: Option, +} + +impl BuilderState { + fn into_builder( + self, + with_roundtrip_builder: bool, + ) -> Result<(Builder, Option), Error> { + let roundtrip_builder = if with_roundtrip_builder { + let mut flags = self.builder.command_line_flags(); + flags.insert(0, "bindgen".into()); + let mut builder = builder_from_flags(flags.into_iter())?.0; + if let Some(ref parse_cb) = self.parse_callbacks { + builder = + builder.parse_callbacks(parse_callbacks::lookup(parse_cb)); + } + Some(BuilderState { + builder, + parse_callbacks: self.parse_callbacks, + }) + } else { + None + }; + Ok((self.builder, roundtrip_builder)) + } +} + +fn create_bindgen_builder(header: &Path) -> Result { + #[cfg(feature = "logging")] + let _ = env_logger::try_init(); + + let source = fs::File::open(header)?; + let reader = BufReader::new(source); + + // Scoop up bindgen-flags from test header + let mut flags = Vec::with_capacity(2); + let mut parse_callbacks = None; + + for line in reader.lines() { + let line = line?; + if !line.starts_with("// bindgen") { + continue; + } + + if line.contains("bindgen-flags: ") { + let extra_flags = line + .split("bindgen-flags: ") + .last() + .and_then(shlex::split) + .unwrap(); + flags.extend(extra_flags); + } else if line.contains("bindgen-osx-only") { + let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"]; + flags = prepend_flags + .iter() + .map(ToString::to_string) + .chain(flags) + .collect(); + } else if line.contains("bindgen-parse-callbacks: ") { + let parse_cb = + line.split("bindgen-parse-callbacks: ").last().unwrap(); + parse_callbacks = Some(parse_cb.to_owned()); + } + } + + // Different platforms have various different conventions like struct padding, mangling, etc. + // We make the default target as x86_64-unknown-linux + if flags.iter().all(|flag| !flag.starts_with("--target=")) { + if !flags.iter().any(|flag| flag == "--") { + flags.push("--".into()); + } + flags.push("--target=x86_64-unknown-linux".into()); + } + + // Fool builder_from_flags() into believing it has real env::args_os... + // - add "bindgen" as executable name 0th element + // - add header filename as 1st element + // - prepend raw lines so they're in the right order for expected output + // - append the test header's bindgen flags + let header_str = header.to_str().ok_or_else(|| { + Error::new(ErrorKind::Other, "Invalid header file name") + })?; + + let prepend = [ + "bindgen", + // We format in `compare_generated_header` ourselves to have a little + // more control. + "--formatter=none", + "--with-derive-default", + "--disable-header-comment", + "--vtable-generation", + header_str, + "--raw-line", + "", + "--raw-line", + "#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]", + "--raw-line", + "", + ]; + + let args = prepend.iter().map(ToString::to_string).chain(flags); + + let mut builder = builder_from_flags(args)?.0; + if let Some(ref parse_cb) = parse_callbacks { + builder = builder.parse_callbacks(parse_callbacks::lookup(parse_cb)); + } + Ok(BuilderState { + builder, + parse_callbacks, + }) +} + +macro_rules! test_header { + ($function:ident, $header:expr) => { + #[test] + fn $function() { + let header = PathBuf::from($header); + let result = create_bindgen_builder(&header).and_then(|builder| { + let check_roundtrip = + env::var_os("BINDGEN_DISABLE_ROUNDTRIP_TEST").is_none(); + compare_generated_header(&header, builder, check_roundtrip) + }); + + if let Err(err) = result { + panic!("{err}"); + } + } + }; +} + +// This file is generated by build.rs +include!(concat!(env!("OUT_DIR"), "/tests.rs")); + +#[test] +#[cfg_attr(target_os = "windows", ignore)] +fn test_clang_env_args() { + env::set_var( + "BINDGEN_EXTRA_CLANG_ARGS", + "-D_ENV_ONE=1 -D_ENV_TWO=\"2 -DNOT_THREE=1\"", + ); + let actual = builder() + .disable_header_comment() + .header_contents( + "test.hpp", + "#ifdef _ENV_ONE\nextern const int x[] = { 42 };\n#endif\n\ + #ifdef _ENV_TWO\nextern const int y[] = { 42 };\n#endif\n\ + #if defined NOT_THREE && NOT_THREE == 1\nextern const int z[] = { 42 };\n#endif\n", + ) + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected = format_code( + "unsafe extern \"C\" { + pub static x: [::std::os::raw::c_int; 1usize]; +} +unsafe extern \"C\" { + pub static y: [::std::os::raw::c_int; 1usize]; +} +", + ) + .unwrap(); + + assert_eq!(expected, actual); +} + +#[test] +fn test_header_contents() { + let actual = builder() + .disable_header_comment() + .header_contents("test.h", "int foo(const char* a);") + .clang_arg("--target=x86_64-unknown-linux") + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected = format_code( + "unsafe extern \"C\" { + pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +", + ) + .unwrap(); + + assert_eq!(expected, actual); +} + +#[test] +fn test_multiple_header_calls_in_builder() { + let actual = builder() + .header(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/headers/func_ptr.h" + )) + .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h")) + .clang_arg("--target=x86_64-unknown-linux") + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected_filename = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs" + ); + let expected = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs" + )); + let expected = format_code(expected).unwrap(); + + if actual != expected { + println!("Generated bindings differ from expected!"); + error_diff_mismatch( + &actual, + &expected, + None, + Path::new(expected_filename), + ) + .unwrap(); + } +} + +#[test] +fn test_headers_call_in_builder() { + let actual = builder() + .headers([ + concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/func_ptr.h"), + concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h"), + ]) + .clang_arg("--target=x86_64-unknown-linux") + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected_filename = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs" + ); + let expected = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs" + )); + let expected = format_code(expected).unwrap(); + + if actual != expected { + println!("Generated bindings differ from expected!"); + error_diff_mismatch( + &actual, + &expected, + None, + Path::new(expected_filename), + ) + .unwrap(); + } +} + +#[test] +fn test_multiple_header_contents() { + let actual = builder() + .header_contents("test.h", "int foo(const char* a);") + .header_contents("test2.h", "float foo2(const char* b);") + .clang_arg("--target=x86_64-unknown-linux") + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected = format_code( + "unsafe extern \"C\" { + pub fn foo2(b: *const ::std::os::raw::c_char) -> f32; +} +unsafe extern \"C\" { + pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +", + ) + .unwrap(); + + assert_eq!(expected, actual); +} + +#[test] +fn test_mixed_header_and_header_contents() { + let actual = builder() + .header(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/headers/func_ptr.h" + )) + .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h")) + .header_contents("test.h", "int bar(const char* a);") + .header_contents("test2.h", "float bar2(const char* b);") + .clang_arg("--target=x86_64-unknown-linux") + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + let expected_filename = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_mixed_header_and_header_contents.rs" + ); + let expected = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_mixed_header_and_header_contents.rs" + )); + let expected = format_code(expected).unwrap(); + if expected != actual { + error_diff_mismatch( + &actual, + &expected, + None, + Path::new(expected_filename), + ) + .unwrap(); + } +} + +#[test] +fn test_macro_fallback_non_system_dir() { + let actual = builder() + .header(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/macro_fallback_test_headers/one_header.h" + )) + .header(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/macro_fallback_test_headers/another_header.h" + )) + .clang_macro_fallback() + .clang_arg(format!("-I{}/tests/headers", env!("CARGO_MANIFEST_DIR"))) + .generate() + .unwrap() + .to_string(); + + let actual = format_code(actual).unwrap(); + + 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 { + error_diff_mismatch( + &actual, + &expected, + None, + Path::new(expected_filename), + ) + .unwrap(); + } +} + +#[test] +// Doesn't support executing sh file on Windows. +// We may want to implement it in Rust so that we support all systems. +#[cfg(not(target_os = "windows"))] +fn no_system_header_includes() { + use std::process::Command; + assert!(Command::new("../ci/no-includes.sh") + .current_dir(env!("CARGO_MANIFEST_DIR")) + .spawn() + .expect("should spawn ../ci/no-includes.sh OK") + .wait() + .expect("should wait for ../ci/no-includes OK") + .success()); +} + +#[test] +fn emit_depfile() { + let header = PathBuf::from("tests/headers/enum-default-rust.h"); + let expected_depfile = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("expectations") + .join("tests") + .join("enum-default-rust.d"); + let observed_depfile = tempfile::NamedTempFile::new().unwrap(); + let mut builder = create_bindgen_builder(&header).unwrap(); + builder.builder = builder.builder.depfile( + "tests/expectations/tests/enum-default-rust.rs", + observed_depfile.path(), + ); + + let check_roundtrip = + env::var_os("BINDGEN_DISABLE_ROUNDTRIP_TEST").is_none(); + let (builder, _roundtrip_builder) = + builder.into_builder(check_roundtrip).unwrap(); + let _bindings = builder.generate().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()); +} + +#[test] +fn dump_preprocessed_input() { + let arg_keyword = + concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/arg_keyword.hpp"); + let empty_layout = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/headers/cpp-empty-layout.hpp" + ); + + builder() + .header(arg_keyword) + .header(empty_layout) + .dump_preprocessed_input() + .expect("should dump preprocessed input"); + + fn slurp(p: &str) -> String { + let mut contents = String::new(); + let mut file = fs::File::open(p).unwrap(); + file.read_to_string(&mut contents).unwrap(); + contents + } + + let bindgen_ii = slurp("__bindgen.ii"); + let arg_keyword = slurp(arg_keyword); + let empty_layout = slurp(empty_layout); + + assert!( + bindgen_ii.contains(&arg_keyword), + "arg_keyword.hpp is in the preprocessed file" + ); + assert!( + bindgen_ii.contains(&empty_layout), + "cpp-empty-layout.hpp is in the preprocessed file" + ); +} + +fn build_flags_output_helper(builder: &Builder) { + let mut command_line_flags = builder.command_line_flags(); + command_line_flags.insert(0, "bindgen".to_string()); + + let flags_quoted: Vec = command_line_flags + .iter() + .map(|x| format!("{}", shlex::try_quote(x).unwrap())) + .collect(); + let flags_str = flags_quoted.join(" "); + println!("{flags_str}"); + + let (builder, _output, _verbose) = + builder_from_flags(command_line_flags.into_iter()).unwrap(); + builder.generate().expect("failed to generate bindings"); +} + +#[test] +fn commandline_multiple_headers() { + let bindings = Builder::default() + .header("tests/headers/char.h") + .header("tests/headers/func_ptr.h") + .header("tests/headers/16-byte-alignment.h"); + build_flags_output_helper(&bindings); +} + +#[test] +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_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()); + + #[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)); + + // 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"); + + let actual_c = fs::read_to_string(generated_path.with_extension("c")) + .expect("Could not read actual wrap_static_fns.c"); + + if expected_c != actual_c { + error_diff_mismatch( + &actual_c, + &expected_c, + None, + &expect_path.with_extension("c"), + ) + .unwrap(); + } +} diff --git a/tests/uses/.gitignore b/bindgen-tests/tests/uses/.gitignore similarity index 100% rename from tests/uses/.gitignore rename to bindgen-tests/tests/uses/.gitignore diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml new file mode 100644 index 0000000000..478574edb3 --- /dev/null +++ b/bindgen/Cargo.toml @@ -0,0 +1,72 @@ +lints.workspace = true + +[package] +authors = [ + "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"] +categories = ["external-ffi-bindings", "development-tools::ffi"] +license = "BSD-3-Clause" +name = "bindgen" +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.72.0" +build = "build.rs" +rust-version.workspace = true +edition.workspace = true + +[lib] +name = "bindgen" +path = "lib.rs" + +[dependencies] +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"] +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 = ["dep:clap", "dep:clap_complete"] +# Features used for CI testing +__testing_only_extra_assertions = [] +__testing_only_libclang_9 = [] +__testing_only_libclang_16 = [] + +[package.metadata.docs.rs] +features = ["experimental"] + +[package.metadata.release] +release = true +pre-release-hook = ["../node_modules/doctoc/doctoc.js", "../CHANGELOG.md"] + +# Add version and date to changelog file +[[package.metadata.release.pre-release-replacements]] +file = "../CHANGELOG.md" +search = "# Unreleased" +replace = "# Unreleased\n## Added\n## Changed\n## Removed\n## Fixed\n## Security\n\n# {{version}} ({{date}})" diff --git a/bindgen/LICENSE b/bindgen/LICENSE new file mode 120000 index 0000000000..ea5b60640b --- /dev/null +++ b/bindgen/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/bindgen/build.rs b/bindgen/build.rs new file mode 100644 index 0000000000..4fb2d3075e --- /dev/null +++ b/bindgen/build.rs @@ -0,0 +1,29 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + let mut dst = + File::create(Path::new(&out_dir).join("host-target.txt")).unwrap(); + dst.write_all(env::var("TARGET").unwrap().as_bytes()) + .unwrap(); + + // On behalf of clang_sys, rebuild ourselves if important configuration + // variables change, to ensure that bindings get rebuilt if the + // underlying libclang changes. + println!("cargo:rerun-if-env-changed=LLVM_CONFIG_PATH"); + println!("cargo:rerun-if-env-changed=LIBCLANG_PATH"); + println!("cargo:rerun-if-env-changed=LIBCLANG_STATIC_PATH"); + println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS"); + println!( + "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", + env::var("TARGET").unwrap() + ); + println!( + "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", + env::var("TARGET").unwrap().replace('-', "_") + ); +} diff --git a/bindgen/callbacks.rs b/bindgen/callbacks.rs new file mode 100644 index 0000000000..c8ac9a5e15 --- /dev/null +++ b/bindgen/callbacks.rs @@ -0,0 +1,337 @@ +//! A public API for more fine-grained customization of bindgen behavior. + +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. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +pub enum MacroParsingBehavior { + /// Ignore the macro, generating no code for it, or anything that depends on + /// it. + Ignore, + /// The default behavior bindgen would have otherwise. + #[default] + Default, +} + +/// A trait to allow configuring different kinds of types in different +/// situations. +pub trait ParseCallbacks: fmt::Debug { + #[cfg(feature = "__cli")] + #[doc(hidden)] + fn cli_args(&self) -> Vec { + vec![] + } + + /// This function will be run on every macro that is identified. + fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { + MacroParsingBehavior::Default + } + + /// This function will run for every extern variable and function. The returned value determines + /// the name visible in the bindings. + fn generated_name_override( + &self, + _item_info: ItemInfo<'_>, + ) -> Option { + None + } + + /// This function will run for every extern variable and function. The returned value determines + /// the link name in the bindings. + fn generated_link_name_override( + &self, + _item_info: ItemInfo<'_>, + ) -> Option { + 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 { + None + } + + /// This will be run on every string macro. The callback cannot influence the further + /// treatment of the macro, but may use the value to generate additional code or configuration. + fn str_macro(&self, _name: &str, _value: &[u8]) {} + + /// This will be run on every function-like macro. The callback cannot + /// influence the further treatment of the macro, but may use the value to + /// generate additional code or configuration. + /// + /// The first parameter represents the name and argument list (including the + /// parentheses) of the function-like macro. The second parameter represents + /// the expansion of the macro as a sequence of tokens. + fn func_macro(&self, _name: &str, _value: &[&[u8]]) {} + + /// This function should return whether, given an enum variant + /// name, and value, this enum variant will forcibly be a constant. + fn enum_variant_behavior( + &self, + _enum_name: Option<&str>, + _original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + None + } + + /// Allows to rename an enum variant, replacing `_original_variant_name`. + fn enum_variant_name( + &self, + _enum_name: Option<&str>, + _original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + None + } + + /// Allows to rename an item, replacing `_item_info.name`. + fn item_name(&self, _item_info: ItemInfo) -> Option { + None + } + + /// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`]. + fn header_file(&self, _filename: &str) {} + + /// This will be called on every file inclusion, with the full path of the included file. + fn include_file(&self, _filename: &str) {} + + /// This will be called every time `bindgen` reads an environment variable whether it has any + /// content or not. + fn read_env_var(&self, _key: &str) {} + + /// This will be called to determine whether a particular blocklisted type + /// implements a trait or not. This will be used to implement traits on + /// other types containing the blocklisted type. + /// + /// * `None`: use the default behavior + /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait` + /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't + /// derive `_derive_trait` but can implemented it manually + /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait` + fn blocklisted_type_implements_trait( + &self, + _name: &str, + _derive_trait: DeriveTrait, + ) -> Option { + None + } + + /// Provide a list of custom derive attributes. + /// + /// If no additional attributes are wanted, this function should return an + /// empty `Vec`. + fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec { + vec![] + } + + /// Provide a list of custom attributes. + /// + /// If no additional attributes are wanted, this function should return an + /// empty `Vec`. + fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec { + vec![] + } + + /// Process a source code comment. + fn process_comment(&self, _comment: &str) -> Option { + None + } + + /// Potentially override the visibility of a composite type field. + /// + /// Caution: This allows overriding standard C++ visibility inferred by + /// `respect_cxx_access_specs`. + fn field_visibility( + &self, + _info: FieldInfo<'_>, + ) -> Option { + None + } + + /// Process a function name that as exactly one `va_list` argument + /// to be wrapped as a variadic function with the wrapped static function + /// feature. + /// + /// The returned string is new function name. + #[cfg(feature = "experimental")] + 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. +} + +/// Relevant information about a type to which new derive attributes will be added using +/// [`ParseCallbacks::add_derives`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] +pub struct DeriveInfo<'a> { + /// The name of the type. + pub name: &'a str, + /// The kind of the type. + pub kind: TypeKind, +} + +/// Relevant information about a type to which new attributes will be added using +/// [`ParseCallbacks::add_attributes`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] +pub struct AttributeInfo<'a> { + /// The name of the type. + pub name: &'a str, + /// The kind of the type. + pub kind: TypeKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +/// The kind of the current type. +pub enum TypeKind { + /// The type is a Rust `struct`. + Struct, + /// The type is a Rust `enum`. + Enum, + /// The type is a Rust `union`. + Union, +} + +/// 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 + pub name: &'a str, + /// The kind of item + pub kind: ItemKind, +} + +/// 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 + Var, +} + +/// Relevant information about a field for which visibility can be determined using +/// [`ParseCallbacks::field_visibility`]. +#[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 new file mode 100644 index 0000000000..9e614da9f8 --- /dev/null +++ b/bindgen/clang.rs @@ -0,0 +1,2449 @@ +//! A higher level Clang API built on top of the generated bindings in the +//! `clang_sys` module. + +#![allow(non_upper_case_globals, dead_code)] +#![deny(clippy::missing_docs_in_private_items)] + +use crate::ir::context::BindgenContext; +use clang_sys::*; +use std::cmp; + +use std::ffi::{CStr, CString}; +use std::fmt; +use std::fs::OpenOptions; +use std::hash::Hash; +use std::hash::Hasher; +use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; +use std::sync::OnceLock; +use std::{mem, ptr, slice}; + +/// Type representing a clang attribute. +/// +/// Values of this type can be used to check for different attributes using the `has_attrs` +/// function. +pub(crate) struct Attribute { + name: &'static [u8], + kind: Option, + token_kind: CXTokenKind, +} + +impl Attribute { + /// A `warn_unused_result` attribute. + pub(crate) const MUST_USE: Self = Self { + name: b"warn_unused_result", + // FIXME(emilio): clang-sys doesn't expose `CXCursor_WarnUnusedResultAttr` (from clang 9). + kind: Some(440), + token_kind: CXToken_Identifier, + }; + + /// A `_Noreturn` attribute. + pub(crate) const NO_RETURN: Self = Self { + name: b"_Noreturn", + kind: None, + token_kind: CXToken_Keyword, + }; + + /// A `[[noreturn]]` attribute. + pub(crate) const NO_RETURN_CPP: Self = Self { + name: b"noreturn", + kind: None, + token_kind: CXToken_Identifier, + }; +} + +/// A cursor into the Clang AST, pointing to an AST node. +/// +/// We call the AST node pointed to by the cursor the cursor's "referent". +#[derive(Copy, Clone)] +pub(crate) struct Cursor { + x: CXCursor, +} + +impl fmt::Debug for Cursor { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!( + fmt, + "Cursor({} kind: {}, loc: {}, usr: {:?})", + self.spelling(), + kind_to_str(self.kind()), + self.location(), + self.usr() + ) + } +} + +impl Cursor { + /// Get the Unified Symbol Resolution for this cursor's referent, if + /// available. + /// + /// The USR can be used to compare entities across translation units. + pub(crate) fn usr(&self) -> Option { + let s = unsafe { cxstring_into_string(clang_getCursorUSR(self.x)) }; + if s.is_empty() { + None + } else { + Some(s) + } + } + + /// Is this cursor's referent a declaration? + pub(crate) fn is_declaration(&self) -> bool { + unsafe { clang_isDeclaration(self.kind()) != 0 } + } + + /// Is this cursor's referent an anonymous record or so? + pub(crate) fn is_anonymous(&self) -> bool { + unsafe { clang_Cursor_isAnonymous(self.x) != 0 } + } + + /// Get this cursor's referent's spelling. + pub(crate) fn spelling(&self) -> String { + unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) } + } + + /// Get this cursor's referent's display name. + /// + /// This is not necessarily a valid identifier. It includes extra + /// information, such as parameters for a function, etc. + pub(crate) fn display_name(&self) -> String { + unsafe { cxstring_into_string(clang_getCursorDisplayName(self.x)) } + } + + /// Get the mangled name of this cursor's referent. + pub(crate) fn mangling(&self) -> String { + unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) } + } + + /// Gets the C++ manglings for this cursor, or an error if the manglings + /// are not available. + pub(crate) fn cxx_manglings(&self) -> Result, ()> { + use clang_sys::*; + unsafe { + let manglings = clang_Cursor_getCXXManglings(self.x); + if manglings.is_null() { + return Err(()); + } + let count = (*manglings).Count as usize; + + let mut result = Vec::with_capacity(count); + for i in 0..count { + let string_ptr = (*manglings).Strings.add(i); + result.push(cxstring_to_string_leaky(*string_ptr)); + } + clang_disposeStringSet(manglings); + Ok(result) + } + } + + /// Returns whether the cursor refers to a built-in definition. + pub(crate) fn is_builtin(&self) -> bool { + let (file, _, _, _) = self.location().location(); + file.name().is_none() + } + + /// Get the `Cursor` for this cursor's referent's lexical parent. + /// + /// The lexical parent is the parent of the definition. The semantic parent + /// is the parent of the declaration. Generally, the lexical parent doesn't + /// have any effect on semantics, while the semantic parent does. + /// + /// In the following snippet, the `Foo` class would be the semantic parent + /// of the out-of-line `method` definition, while the lexical parent is the + /// translation unit. + /// + /// ```c++ + /// class Foo { + /// void method(); + /// }; + /// + /// void Foo::method() { /* ... */ } + /// ``` + pub(crate) fn lexical_parent(&self) -> Cursor { + unsafe { + Cursor { + x: clang_getCursorLexicalParent(self.x), + } + } + } + + /// Get the referent's semantic parent, if one is available. + /// + /// See documentation for `lexical_parent` for details on semantic vs + /// lexical parents. + pub(crate) fn fallible_semantic_parent(&self) -> Option { + let sp = unsafe { + Cursor { + x: clang_getCursorSemanticParent(self.x), + } + }; + if sp == *self || !sp.is_valid() { + return None; + } + Some(sp) + } + + /// Get the referent's semantic parent. + /// + /// See documentation for `lexical_parent` for details on semantic vs + /// lexical parents. + pub(crate) fn semantic_parent(&self) -> Cursor { + self.fallible_semantic_parent().unwrap() + } + + /// Return the number of template arguments used by this cursor's referent, + /// if the referent is either a template instantiation. Returns `None` + /// otherwise. + /// + /// NOTE: This may not return `Some` for partial template specializations, + /// see #193 and #194. + pub(crate) fn num_template_args(&self) -> Option { + // XXX: `clang_Type_getNumTemplateArguments` is sort of reliable, while + // `clang_Cursor_getNumTemplateArguments` is totally unreliable. + // Therefore, try former first, and only fallback to the latter if we + // have to. + self.cur_type() + .num_template_args() + .or_else(|| { + let n: c_int = + unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; + + if n >= 0 { + Some(n as u32) + } else { + debug_assert_eq!(n, -1); + None + } + }) + .or_else(|| { + let canonical = self.canonical(); + if canonical == *self { + None + } else { + canonical.num_template_args() + } + }) + } + + /// Get a cursor pointing to this referent's containing translation unit. + /// + /// Note that we shouldn't create a `TranslationUnit` struct here, because + /// bindgen assumes there will only be one of them alive at a time, and + /// disposes it on drop. That can change if this would be required, but I + /// think we can survive fine without it. + pub(crate) fn translation_unit(&self) -> Cursor { + assert!(self.is_valid()); + unsafe { + let tu = clang_Cursor_getTranslationUnit(self.x); + let cursor = Cursor { + x: clang_getTranslationUnitCursor(tu), + }; + assert!(cursor.is_valid()); + cursor + } + } + + /// Is the referent a top level construct? + pub(crate) fn is_toplevel(&self) -> bool { + let mut semantic_parent = self.fallible_semantic_parent(); + + while semantic_parent.is_some() && + (semantic_parent.unwrap().kind() == CXCursor_Namespace || + semantic_parent.unwrap().kind() == + CXCursor_NamespaceAlias || + semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) + { + semantic_parent = + semantic_parent.unwrap().fallible_semantic_parent(); + } + + let tu = self.translation_unit(); + // Yes, this can happen with, e.g., macro definitions. + semantic_parent == tu.fallible_semantic_parent() + } + + /// There are a few kinds of types that we need to treat specially, mainly + /// not tracking the type declaration but the location of the cursor, given + /// clang doesn't expose a proper declaration for these types. + pub(crate) fn is_template_like(&self) -> bool { + matches!( + self.kind(), + CXCursor_ClassTemplate | + CXCursor_ClassTemplatePartialSpecialization | + CXCursor_TypeAliasTemplateDecl + ) + } + + /// Is this Cursor pointing to a function-like macro definition? + pub(crate) fn is_macro_function_like(&self) -> bool { + unsafe { clang_Cursor_isMacroFunctionLike(self.x) != 0 } + } + + /// Get the kind of referent this cursor is pointing to. + pub(crate) fn kind(&self) -> CXCursorKind { + self.x.kind + } + + /// Returns true if the cursor is a definition + pub(crate) fn is_definition(&self) -> bool { + unsafe { clang_isCursorDefinition(self.x) != 0 } + } + + /// Is the referent a template specialization? + pub(crate) fn is_template_specialization(&self) -> bool { + self.specialized().is_some() + } + + /// Is the referent a fully specialized template specialization without any + /// remaining free template arguments? + pub(crate) fn is_fully_specialized_template(&self) -> bool { + self.is_template_specialization() && + self.kind() != CXCursor_ClassTemplatePartialSpecialization && + self.num_template_args().unwrap_or(0) > 0 + } + + /// Is the referent a template specialization that still has remaining free + /// template arguments? + pub(crate) fn is_in_non_fully_specialized_template(&self) -> bool { + if self.is_toplevel() { + return false; + } + + let parent = self.semantic_parent(); + if parent.is_fully_specialized_template() { + return false; + } + + if !parent.is_template_like() { + return parent.is_in_non_fully_specialized_template(); + } + + true + } + + /// Is the referent any kind of template parameter? + pub(crate) fn is_template_parameter(&self) -> bool { + matches!( + self.kind(), + CXCursor_TemplateTemplateParameter | + CXCursor_TemplateTypeParameter | + CXCursor_NonTypeTemplateParameter + ) + } + + /// Does the referent's type or value depend on a template parameter? + pub(crate) fn is_dependent_on_template_parameter(&self) -> bool { + fn visitor( + found_template_parameter: &mut bool, + cur: Cursor, + ) -> CXChildVisitResult { + // If we found a template parameter, it is dependent. + if cur.is_template_parameter() { + *found_template_parameter = true; + return CXChildVisit_Break; + } + + // Get the referent and traverse it as well. + if let Some(referenced) = cur.referenced() { + if referenced.is_template_parameter() { + *found_template_parameter = true; + return CXChildVisit_Break; + } + + referenced + .visit(|next| visitor(found_template_parameter, next)); + if *found_template_parameter { + return CXChildVisit_Break; + } + } + + // Continue traversing the AST at the original cursor. + CXChildVisit_Recurse + } + + if self.is_template_parameter() { + return true; + } + + let mut found_template_parameter = false; + self.visit(|next| visitor(&mut found_template_parameter, next)); + + found_template_parameter + } + + /// Is this cursor pointing a valid referent? + pub(crate) fn is_valid(&self) -> bool { + unsafe { clang_isInvalid(self.kind()) == 0 } + } + + /// Get the source location for the referent. + pub(crate) fn location(&self) -> SourceLocation { + unsafe { + SourceLocation { + x: clang_getCursorLocation(self.x), + } + } + } + + /// Get the source location range for the referent. + pub(crate) fn extent(&self) -> CXSourceRange { + unsafe { clang_getCursorExtent(self.x) } + } + + /// Get the raw declaration comment for this referent, if one exists. + pub(crate) fn raw_comment(&self) -> Option { + let s = unsafe { + cxstring_into_string(clang_Cursor_getRawCommentText(self.x)) + }; + if s.is_empty() { + None + } else { + Some(s) + } + } + + /// Get the referent's parsed comment. + pub(crate) fn comment(&self) -> Comment { + unsafe { + Comment { + x: clang_Cursor_getParsedComment(self.x), + } + } + } + + /// Get the referent's type. + pub(crate) fn cur_type(&self) -> Type { + unsafe { + Type { + x: clang_getCursorType(self.x), + } + } + } + + /// Given that this cursor's referent is a reference to another type, or is + /// a declaration, get the cursor pointing to the referenced type or type of + /// the declared thing. + pub(crate) fn definition(&self) -> Option { + unsafe { + let ret = Cursor { + x: clang_getCursorDefinition(self.x), + }; + + if ret.is_valid() && ret.kind() != CXCursor_NoDeclFound { + Some(ret) + } else { + None + } + } + } + + /// Given that this cursor's referent is reference type, get the cursor + /// pointing to the referenced type. + pub(crate) fn referenced(&self) -> Option { + unsafe { + let ret = Cursor { + x: clang_getCursorReferenced(self.x), + }; + + if ret.is_valid() { + Some(ret) + } else { + None + } + } + } + + /// Get the canonical cursor for this referent. + /// + /// Many types can be declared multiple times before finally being properly + /// defined. This method allows us to get the canonical cursor for the + /// referent type. + pub(crate) fn canonical(&self) -> Cursor { + unsafe { + Cursor { + x: clang_getCanonicalCursor(self.x), + } + } + } + + /// Given that this cursor points to either a template specialization or a + /// template instantiation, get a cursor pointing to the template definition + /// that is being specialized. + pub(crate) fn specialized(&self) -> Option { + unsafe { + let ret = Cursor { + x: clang_getSpecializedCursorTemplate(self.x), + }; + if ret.is_valid() { + Some(ret) + } else { + None + } + } + } + + /// Assuming that this cursor's referent is a template declaration, get the + /// kind of cursor that would be generated for its specializations. + pub(crate) fn template_kind(&self) -> CXCursorKind { + unsafe { clang_getTemplateCursorKind(self.x) } + } + + /// Traverse this cursor's referent and its children. + /// + /// Call the given function on each AST node traversed. + pub(crate) fn visit(&self, mut visitor: Visitor) + where + Visitor: FnMut(Cursor) -> CXChildVisitResult, + { + let data = ptr::addr_of_mut!(visitor); + unsafe { + clang_visitChildren(self.x, visit_children::, data.cast()); + } + } + + /// Traverse all of this cursor's children, sorted by where they appear in source code. + /// + /// Call the given function on each AST node traversed. + pub(crate) fn visit_sorted( + &self, + ctx: &mut BindgenContext, + mut visitor: Visitor, + ) where + Visitor: FnMut(&mut BindgenContext, Cursor), + { + // FIXME(#2556): The current source order stuff doesn't account well for different levels + // of includes, or includes that show up at the same byte offset because they are passed in + // via CLI. + const SOURCE_ORDER_ENABLED: bool = false; + if !SOURCE_ORDER_ENABLED { + return self.visit(|c| { + visitor(ctx, c); + CXChildVisit_Continue + }); + } + + let mut children = self.collect_children(); + for child in &children { + if child.kind() == CXCursor_InclusionDirective { + if let Some(included_file) = child.get_included_file_name() { + let location = child.location(); + let (source_file, _, _, offset) = location.location(); + + if let Some(source_file) = source_file.name() { + ctx.add_include(source_file, included_file, offset); + } + } + } + } + children + .sort_by(|child1, child2| child1.cmp_by_source_order(child2, ctx)); + for child in children { + visitor(ctx, child); + } + } + + /// Compare source order of two cursors, considering `#include` directives. + /// + /// Built-in items provided by the compiler (which don't have a source file), + /// are sorted first. Remaining files are sorted by their position in the source file. + /// If the items' source files differ, they are sorted by the position of the first + /// `#include` for their source file. If no source files are included, `None` is returned. + fn cmp_by_source_order( + &self, + other: &Self, + ctx: &BindgenContext, + ) -> cmp::Ordering { + let (file, _, _, offset) = self.location().location(); + let (other_file, _, _, other_offset) = other.location().location(); + + let (file, other_file) = match (file.name(), other_file.name()) { + (Some(file), Some(other_file)) => (file, other_file), + // Built-in definitions should come first. + (Some(_), None) => return cmp::Ordering::Greater, + (None, Some(_)) => return cmp::Ordering::Less, + (None, None) => return cmp::Ordering::Equal, + }; + + if file == other_file { + // Both items are in the same source file, compare by byte offset. + return offset.cmp(&other_offset); + } + + let include_location = ctx.included_file_location(&file); + let other_include_location = ctx.included_file_location(&other_file); + match (include_location, other_include_location) { + (Some((file2, offset2)), _) if file2 == other_file => { + offset2.cmp(&other_offset) + } + (Some(_), None) => cmp::Ordering::Greater, + (_, Some((other_file2, other_offset2))) if file == other_file2 => { + offset.cmp(&other_offset2) + } + (None, Some(_)) => cmp::Ordering::Less, + (Some((file2, offset2)), Some((other_file2, other_offset2))) => { + if file2 == other_file2 { + offset2.cmp(&other_offset2) + } else { + cmp::Ordering::Equal + } + } + (None, None) => cmp::Ordering::Equal, + } + } + + /// Collect all of this cursor's children into a vec and return them. + pub(crate) fn collect_children(&self) -> Vec { + let mut children = vec![]; + self.visit(|c| { + children.push(c); + CXChildVisit_Continue + }); + children + } + + /// Does this cursor have any children? + pub(crate) fn has_children(&self) -> bool { + let mut has_children = false; + self.visit(|_| { + has_children = true; + CXChildVisit_Break + }); + has_children + } + + /// Does this cursor have at least `n` children? + pub(crate) fn has_at_least_num_children(&self, n: usize) -> bool { + assert!(n > 0); + let mut num_left = n; + self.visit(|_| { + num_left -= 1; + if num_left == 0 { + CXChildVisit_Break + } else { + CXChildVisit_Continue + } + }); + num_left == 0 + } + + /// Returns whether the given location contains a cursor with the given + /// kind in the first level of nesting underneath (doesn't look + /// recursively). + pub(crate) fn contains_cursor(&self, kind: CXCursorKind) -> bool { + let mut found = false; + + self.visit(|c| { + if c.kind() == kind { + found = true; + CXChildVisit_Break + } else { + CXChildVisit_Continue + } + }); + + found + } + + /// Is the referent an inlined function? + pub(crate) fn is_inlined_function(&self) -> bool { + unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } + } + + /// Is the referent a defaulted function? + pub(crate) fn is_defaulted_function(&self) -> bool { + unsafe { clang_CXXMethod_isDefaulted(self.x) != 0 } + } + + /// Is the referent a deleted function? + pub(crate) fn is_deleted_function(&self) -> bool { + // Unfortunately, libclang doesn't yet have an API for checking if a + // member function is deleted, but the following should be a good + // enough approximation. + // Deleted functions are implicitly inline according to paragraph 4 of + // [dcl.fct.def.delete] in the C++ standard. Normal inline functions + // have a definition in the same translation unit, so if this is an + // inline function without a definition, and it's not a defaulted + // function, we can reasonably safely conclude that it's a deleted + // function. + self.is_inlined_function() && + self.definition().is_none() && + !self.is_defaulted_function() + } + + /// Is the referent a bit field declaration? + pub(crate) fn is_bit_field(&self) -> bool { + unsafe { clang_Cursor_isBitField(self.x) != 0 } + } + + /// Get a cursor to the bit field's width expression, or `None` if it's not + /// a bit field. + pub(crate) fn bit_width_expr(&self) -> Option { + if !self.is_bit_field() { + return None; + } + + let mut result = None; + self.visit(|cur| { + // The first child may or may not be a TypeRef, depending on whether + // the field's type is builtin. Skip it. + if cur.kind() == CXCursor_TypeRef { + return CXChildVisit_Continue; + } + + // The next expression or literal is the bit width. + result = Some(cur); + + CXChildVisit_Break + }); + + result + } + + /// Get the width of this cursor's referent bit field, or `None` if the + /// referent is not a bit field or if the width could not be evaluated. + pub(crate) fn bit_width(&self) -> Option { + // It is not safe to check the bit width without ensuring it doesn't + // depend on a template parameter. See + // https://github.com/rust-lang/rust-bindgen/issues/2239 + if self.bit_width_expr()?.is_dependent_on_template_parameter() { + return None; + } + + unsafe { + let w = clang_getFieldDeclBitWidth(self.x); + if w == -1 { + None + } else { + Some(w as u32) + } + } + } + + /// Get the integer representation type used to hold this cursor's referent + /// enum type. + pub(crate) fn enum_type(&self) -> Option { + unsafe { + let t = Type { + x: clang_getEnumDeclIntegerType(self.x), + }; + if t.is_valid() { + Some(t) + } else { + None + } + } + } + + /// Get the boolean constant value for this cursor's enum variant referent. + /// + /// Returns None if the cursor's referent is not an enum variant. + pub(crate) fn enum_val_boolean(&self) -> Option { + unsafe { + if self.kind() == CXCursor_EnumConstantDecl { + Some(clang_getEnumConstantDeclValue(self.x) != 0) + } else { + None + } + } + } + + /// Get the signed constant value for this cursor's enum variant referent. + /// + /// Returns None if the cursor's referent is not an enum variant. + pub(crate) fn enum_val_signed(&self) -> Option { + unsafe { + if self.kind() == CXCursor_EnumConstantDecl { + #[allow(clippy::unnecessary_cast)] + Some(clang_getEnumConstantDeclValue(self.x) as i64) + } else { + None + } + } + } + + /// Get the unsigned constant value for this cursor's enum variant referent. + /// + /// Returns None if the cursor's referent is not an enum variant. + pub(crate) fn enum_val_unsigned(&self) -> Option { + unsafe { + if self.kind() == CXCursor_EnumConstantDecl { + #[allow(clippy::unnecessary_cast)] + Some(clang_getEnumConstantDeclUnsignedValue(self.x) as u64) + } else { + None + } + } + } + + /// Does this cursor have the given attributes? + pub(crate) fn has_attrs( + &self, + attrs: &[Attribute; N], + ) -> [bool; N] { + let mut found_attrs = [false; N]; + let mut found_count = 0; + + self.visit(|cur| { + let kind = cur.kind(); + for (idx, attr) in attrs.iter().enumerate() { + 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 == Some(kind) || + (kind == CXCursor_UnexposedAttr && + cur.tokens().iter().any(|t| { + t.kind == attr.token_kind && + t.spelling() == attr.name + })) + { + *found_attr = true; + found_count += 1; + + if found_count == N { + return CXChildVisit_Break; + } + } + } + } + + CXChildVisit_Continue + }); + + found_attrs + } + + /// Given that this cursor's referent is a `typedef`, get the `Type` that is + /// being aliased. + pub(crate) fn typedef_type(&self) -> Option { + let inner = Type { + x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) }, + }; + + if inner.is_valid() { + Some(inner) + } else { + None + } + } + + /// Get the linkage kind for this cursor's referent. + /// + /// This only applies to functions and variables. + pub(crate) fn linkage(&self) -> CXLinkageKind { + unsafe { clang_getCursorLinkage(self.x) } + } + + /// Get the visibility of this cursor's referent. + pub(crate) fn visibility(&self) -> CXVisibilityKind { + unsafe { clang_getCursorVisibility(self.x) } + } + + /// Given that this cursor's referent is a function, return cursors to its + /// parameters. + /// + /// Returns None if the cursor's referent is not a function/method call or + /// declaration. + pub(crate) fn args(&self) -> Option> { + // match self.kind() { + // CXCursor_FunctionDecl | + // CXCursor_CXXMethod => { + self.num_args().ok().map(|num| { + (0..num) + .map(|i| Cursor { + x: unsafe { clang_Cursor_getArgument(self.x, i as c_uint) }, + }) + .collect() + }) + } + + /// Given that this cursor's referent is a function/method call or + /// declaration, return the number of arguments it takes. + /// + /// Returns Err if the cursor's referent is not a function/method call or + /// declaration. + pub(crate) fn num_args(&self) -> Result { + unsafe { + let w = clang_Cursor_getNumArguments(self.x); + if w == -1 { + Err(()) + } else { + Ok(w as u32) + } + } + } + + /// Get the access specifier for this cursor's referent. + pub(crate) fn access_specifier(&self) -> CX_CXXAccessSpecifier { + unsafe { clang_getCXXAccessSpecifier(self.x) } + } + + /// Is the cursor's referent publicly accessible in C++? + /// + /// Returns true if `self.access_specifier()` is `CX_CXXPublic` or + /// `CX_CXXInvalidAccessSpecifier`. + pub(crate) fn public_accessible(&self) -> bool { + let access = self.access_specifier(); + access == CX_CXXPublic || access == CX_CXXInvalidAccessSpecifier + } + + /// Is this cursor's referent a field declaration that is marked as + /// `mutable`? + pub(crate) fn is_mutable_field(&self) -> bool { + unsafe { clang_CXXField_isMutable(self.x) != 0 } + } + + /// Get the offset of the field represented by the Cursor. + pub(crate) fn offset_of_field(&self) -> Result { + let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) }; + + if offset < 0 { + Err(LayoutError::from(offset as i32)) + } else { + Ok(offset as usize) + } + } + + /// Is this cursor's referent a member function that is declared `static`? + pub(crate) fn method_is_static(&self) -> bool { + unsafe { clang_CXXMethod_isStatic(self.x) != 0 } + } + + /// Is this cursor's referent a member function that is declared `const`? + pub(crate) fn method_is_const(&self) -> bool { + unsafe { clang_CXXMethod_isConst(self.x) != 0 } + } + + /// Is this cursor's referent a member function that is virtual? + pub(crate) fn method_is_virtual(&self) -> bool { + unsafe { clang_CXXMethod_isVirtual(self.x) != 0 } + } + + /// Is this cursor's referent a member function that is pure virtual? + pub(crate) fn method_is_pure_virtual(&self) -> bool { + unsafe { clang_CXXMethod_isPureVirtual(self.x) != 0 } + } + + /// Is this cursor's referent a struct or class with virtual members? + pub(crate) fn is_virtual_base(&self) -> bool { + unsafe { clang_isVirtualBase(self.x) != 0 } + } + + /// Try to evaluate this cursor. + pub(crate) fn evaluate(&self) -> Option { + EvalResult::new(*self) + } + + /// Return the result type for this cursor + pub(crate) fn ret_type(&self) -> Option { + let rt = Type { + x: unsafe { clang_getCursorResultType(self.x) }, + }; + if rt.is_valid() { + Some(rt) + } else { + None + } + } + + /// Gets the tokens that correspond to that cursor. + pub(crate) fn tokens(&self) -> RawTokens<'_> { + RawTokens::new(self) + } + + /// Gets the tokens that correspond to that cursor as `cexpr` tokens. + pub(crate) fn cexpr_tokens(self) -> Vec { + self.tokens() + .iter() + .filter_map(|token| token.as_cexpr_token()) + .collect() + } + + /// 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_getIncludedFile(self.x) }; + if file.is_null() { + None + } else { + 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. +pub(crate) struct RawTokens<'a> { + cursor: &'a Cursor, + tu: CXTranslationUnit, + tokens: *mut CXToken, + token_count: c_uint, +} + +impl<'a> RawTokens<'a> { + fn new(cursor: &'a Cursor) -> Self { + let mut tokens = ptr::null_mut(); + let mut token_count = 0; + let range = cursor.extent(); + let tu = unsafe { clang_Cursor_getTranslationUnit(cursor.x) }; + unsafe { clang_tokenize(tu, range, &mut tokens, &mut token_count) }; + Self { + cursor, + tu, + tokens, + token_count, + } + } + + fn as_slice(&self) -> &[CXToken] { + if self.tokens.is_null() { + return &[]; + } + unsafe { slice::from_raw_parts(self.tokens, self.token_count as usize) } + } + + /// Get an iterator over these tokens. + pub(crate) fn iter(&self) -> ClangTokenIterator<'_> { + ClangTokenIterator { + tu: self.tu, + raw: self.as_slice().iter(), + } + } +} + +impl Drop for RawTokens<'_> { + fn drop(&mut self) { + if !self.tokens.is_null() { + unsafe { + clang_disposeTokens( + self.tu, + self.tokens, + self.token_count as c_uint, + ); + } + } + } +} + +/// A raw clang token, that exposes only kind, spelling, and extent. This is a +/// slightly more convenient version of `CXToken` which owns the spelling +/// string and extent. +#[derive(Debug)] +pub(crate) struct ClangToken { + spelling: CXString, + /// The extent of the token. This is the same as the relevant member from + /// `CXToken`. + pub(crate) extent: CXSourceRange, + /// The kind of the token. This is the same as the relevant member from + /// `CXToken`. + pub(crate) kind: CXTokenKind, +} + +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)) }; + c_str.to_bytes() + } + + /// Converts a `ClangToken` to a `cexpr` token if possible. + pub(crate) fn as_cexpr_token(&self) -> Option { + use cexpr::token; + + let kind = match self.kind { + CXToken_Punctuation => token::Kind::Punctuation, + CXToken_Literal => token::Kind::Literal, + CXToken_Identifier => token::Kind::Identifier, + CXToken_Keyword => token::Kind::Keyword, + // NB: cexpr is not too happy about comments inside + // expressions, so we strip them down here. + CXToken_Comment => return None, + _ => { + warn!("Found unexpected token kind: {self:?}"); + return None; + } + }; + + Some(token::Token { + kind, + raw: self.spelling().to_vec().into_boxed_slice(), + }) + } +} + +impl Drop for ClangToken { + fn drop(&mut self) { + unsafe { clang_disposeString(self.spelling) } + } +} + +/// An iterator over a set of Tokens. +pub(crate) struct ClangTokenIterator<'a> { + tu: CXTranslationUnit, + raw: slice::Iter<'a, CXToken>, +} + +impl Iterator for ClangTokenIterator<'_> { + type Item = ClangToken; + + fn next(&mut self) -> Option { + let raw = self.raw.next()?; + unsafe { + let kind = clang_getTokenKind(*raw); + let spelling = clang_getTokenSpelling(self.tu, *raw); + let extent = clang_getTokenExtent(self.tu, *raw); + Some(ClangToken { + spelling, + extent, + kind, + }) + } + } +} + +/// Checks whether the name looks like an identifier, i.e. is alphanumeric +/// (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().is_some_and(|c| c.is_alphabetic() || c == '_'); + + first_valid && chars.all(|c| c.is_alphanumeric() || c == '_') +} + +extern "C" fn visit_children( + cur: CXCursor, + _parent: CXCursor, + data: CXClientData, +) -> CXChildVisitResult +where + Visitor: FnMut(Cursor) -> CXChildVisitResult, +{ + let func: &mut Visitor = unsafe { &mut *data.cast::() }; + let child = Cursor { x: cur }; + + (*func)(child) +} + +impl PartialEq for Cursor { + fn eq(&self, other: &Cursor) -> bool { + unsafe { clang_equalCursors(self.x, other.x) == 1 } + } +} + +impl Eq for Cursor {} + +impl Hash for Cursor { + fn hash(&self, state: &mut H) { + unsafe { clang_hashCursor(self.x) }.hash(state); + } +} + +/// The type of a node in clang's AST. +#[derive(Clone, Copy)] +pub(crate) struct Type { + x: CXType, +} + +impl PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + unsafe { clang_equalTypes(self.x, other.x) != 0 } + } +} + +impl Eq for Type {} + +impl fmt::Debug for Type { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!( + fmt, + "Type({}, kind: {}, cconv: {}, decl: {:?}, canon: {:?})", + self.spelling(), + type_to_str(self.kind()), + self.call_conv(), + self.declaration(), + self.declaration().canonical() + ) + } +} + +/// An error about the layout of a struct, class, or type. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub(crate) enum LayoutError { + /// Asked for the layout of an invalid type. + Invalid, + /// Asked for the layout of an incomplete type. + Incomplete, + /// Asked for the layout of a dependent type. + Dependent, + /// Asked for the layout of a type that does not have constant size. + NotConstantSize, + /// Asked for the layout of a field in a type that does not have such a + /// field. + InvalidFieldName, + /// An unknown layout error. + Unknown, +} + +impl ::std::convert::From for LayoutError { + fn from(val: i32) -> Self { + use self::LayoutError::*; + + match val { + CXTypeLayoutError_Invalid => Invalid, + CXTypeLayoutError_Incomplete => Incomplete, + CXTypeLayoutError_Dependent => Dependent, + CXTypeLayoutError_NotConstantSize => NotConstantSize, + CXTypeLayoutError_InvalidFieldName => InvalidFieldName, + _ => Unknown, + } + } +} + +impl Type { + /// Get this type's kind. + pub(crate) fn kind(&self) -> CXTypeKind { + self.x.kind + } + + /// Get a cursor pointing to this type's declaration. + pub(crate) fn declaration(&self) -> Cursor { + 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. + pub(crate) fn canonical_declaration( + &self, + location: Option<&Cursor>, + ) -> Option { + let mut declaration = self.declaration(); + if !declaration.is_valid() { + if let Some(location) = location { + let mut location = *location; + if let Some(referenced) = location.referenced() { + location = referenced; + } + if location.is_template_like() { + declaration = location; + } + } + } + + let canonical = declaration.canonical(); + if canonical.is_valid() && canonical.kind() != CXCursor_NoDeclFound { + Some(CanonicalTypeDeclaration(*self, canonical)) + } else { + None + } + } + + /// Get a raw display name for this type. + pub(crate) fn spelling(&self) -> String { + let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }; + // Clang 5.0 introduced changes in the spelling API so it returned the + // full qualified name. Let's undo that here. + if s.split("::").all(is_valid_identifier) { + if let Some(s) = s.split("::").last() { + return s.to_owned(); + } + } + + s + } + + /// Is this type const qualified? + pub(crate) fn is_const(&self) -> bool { + unsafe { clang_isConstQualifiedType(self.x) != 0 } + } + + #[inline] + fn is_non_deductible_auto_type(&self) -> bool { + debug_assert_eq!(self.kind(), CXType_Auto); + self.canonical_type() == *self + } + + #[inline] + fn clang_size_of(&self, ctx: &BindgenContext) -> c_longlong { + match self.kind() { + // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975 + CXType_RValueReference | CXType_LValueReference => { + ctx.target_pointer_size() as c_longlong + } + // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 + CXType_Auto if self.is_non_deductible_auto_type() => -6, + _ => unsafe { clang_Type_getSizeOf(self.x) }, + } + } + + #[inline] + fn clang_align_of(&self, ctx: &BindgenContext) -> c_longlong { + match self.kind() { + // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975 + CXType_RValueReference | CXType_LValueReference => { + ctx.target_pointer_size() as c_longlong + } + // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 + CXType_Auto if self.is_non_deductible_auto_type() => -6, + _ => unsafe { clang_Type_getAlignOf(self.x) }, + } + } + + /// What is the size of this type? Paper over invalid types by returning `0` + /// for them. + pub(crate) fn size(&self, ctx: &BindgenContext) -> usize { + let val = self.clang_size_of(ctx); + if val < 0 { + 0 + } else { + val as usize + } + } + + /// What is the size of this type? + pub(crate) fn fallible_size( + &self, + ctx: &BindgenContext, + ) -> Result { + let val = self.clang_size_of(ctx); + if val < 0 { + Err(LayoutError::from(val as i32)) + } else { + Ok(val as usize) + } + } + + /// What is the alignment of this type? Paper over invalid types by + /// returning `0`. + pub(crate) fn align(&self, ctx: &BindgenContext) -> usize { + let val = self.clang_align_of(ctx); + if val < 0 { + 0 + } else { + val as usize + } + } + + /// What is the alignment of this type? + pub(crate) fn fallible_align( + &self, + ctx: &BindgenContext, + ) -> Result { + let val = self.clang_align_of(ctx); + if val < 0 { + Err(LayoutError::from(val as i32)) + } else { + Ok(val as usize) + } + } + + /// Get the layout for this type, or an error describing why it does not + /// have a valid layout. + pub(crate) fn fallible_layout( + &self, + ctx: &BindgenContext, + ) -> Result { + use crate::ir::layout::Layout; + let size = self.fallible_size(ctx)?; + let align = self.fallible_align(ctx)?; + Ok(Layout::new(size, align)) + } + + /// Get the number of template arguments this type has, or `None` if it is + /// not some kind of template. + pub(crate) fn num_template_args(&self) -> Option { + let n = unsafe { clang_Type_getNumTemplateArguments(self.x) }; + if n >= 0 { + Some(n as u32) + } else { + debug_assert_eq!(n, -1); + None + } + } + + /// If this type is a class template specialization, return its + /// template arguments. Otherwise, return None. + pub(crate) fn template_args(&self) -> Option { + self.num_template_args().map(|n| TypeTemplateArgIterator { + x: self.x, + length: n, + index: 0, + }) + } + + /// Given that this type is a function prototype, return the types of its parameters. + /// + /// Returns None if the type is not a function prototype. + pub(crate) fn args(&self) -> Option> { + self.num_args().ok().map(|num| { + (0..num) + .map(|i| Type { + x: unsafe { clang_getArgType(self.x, i as c_uint) }, + }) + .collect() + }) + } + + /// Given that this type is a function prototype, return the number of arguments it takes. + /// + /// Returns Err if the type is not a function prototype. + pub(crate) fn num_args(&self) -> Result { + unsafe { + let w = clang_getNumArgTypes(self.x); + if w == -1 { + Err(()) + } else { + Ok(w as u32) + } + } + } + + /// Given that this type is a pointer type, return the type that it points + /// to. + pub(crate) fn pointee_type(&self) -> Option { + match self.kind() { + CXType_Pointer | + CXType_RValueReference | + CXType_LValueReference | + CXType_MemberPointer | + CXType_BlockPointer | + CXType_ObjCObjectPointer => { + let ret = Type { + x: unsafe { clang_getPointeeType(self.x) }, + }; + debug_assert!(ret.is_valid()); + Some(ret) + } + _ => None, + } + } + + /// Given that this type is an array, vector, or complex type, return the + /// type of its elements. + pub(crate) fn elem_type(&self) -> Option { + let current_type = Type { + x: unsafe { clang_getElementType(self.x) }, + }; + if current_type.is_valid() { + Some(current_type) + } else { + None + } + } + + /// Given that this type is an array or vector type, return its number of + /// elements. + pub(crate) fn num_elements(&self) -> Option { + let num_elements_returned = unsafe { clang_getNumElements(self.x) }; + if num_elements_returned == -1 { + None + } else { + Some(num_elements_returned as usize) + } + } + + /// Get the canonical version of this type. This sees through `typedef`s and + /// aliases to get the underlying, canonical type. + pub(crate) fn canonical_type(&self) -> Type { + unsafe { + Type { + x: clang_getCanonicalType(self.x), + } + } + } + + /// Is this type a variadic function type? + pub(crate) fn is_variadic(&self) -> bool { + unsafe { clang_isFunctionTypeVariadic(self.x) != 0 } + } + + /// Given that this type is a function type, get the type of its return + /// value. + pub(crate) fn ret_type(&self) -> Option { + let rt = Type { + x: unsafe { clang_getResultType(self.x) }, + }; + if rt.is_valid() { + Some(rt) + } else { + None + } + } + + /// Given that this type is a function type, get its calling convention. If + /// this is not a function type, `CXCallingConv_Invalid` is returned. + pub(crate) fn call_conv(&self) -> CXCallingConv { + unsafe { clang_getFunctionTypeCallingConv(self.x) } + } + + /// For elaborated types (types which use `class`, `struct`, or `union` to + /// disambiguate types from local bindings), get the underlying type. + pub(crate) fn named(&self) -> Type { + unsafe { + Type { + x: clang_Type_getNamedType(self.x), + } + } + } + + /// For atomic types, get the underlying type. + pub(crate) fn atomic_value_type(&self) -> Type { + unsafe { + Type { + x: clang_Type_getValueType(self.x), + } + } + } + + /// Is this a valid type? + pub(crate) fn is_valid(&self) -> bool { + self.kind() != CXType_Invalid + } + + /// Is this a valid and exposed type? + pub(crate) fn is_valid_and_exposed(&self) -> bool { + self.is_valid() && self.kind() != CXType_Unexposed + } + + /// Is this type a fully instantiated template? + pub(crate) fn is_fully_instantiated_template(&self) -> bool { + // 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().is_some_and(|args| args.len() > 0) && + !matches!( + self.declaration().kind(), + CXCursor_ClassTemplatePartialSpecialization | + CXCursor_TypeAliasTemplateDecl | + CXCursor_TemplateTemplateParameter + ) + } + + /// Is this type an associated template type? Eg `T::Associated` in + /// this example: + /// + /// ```c++ + /// template + /// class Foo { + /// typename T::Associated member; + /// }; + /// ``` + pub(crate) fn is_associated_type(&self) -> bool { + // This is terrible :( + fn hacky_parse_associated_type>(spelling: S) -> bool { + static ASSOC_TYPE_RE: OnceLock = OnceLock::new(); + ASSOC_TYPE_RE + .get_or_init(|| { + regex::Regex::new(r"typename type\-parameter\-\d+\-\d+::.+") + .unwrap() + }) + .is_match(spelling.as_ref()) + } + + self.kind() == CXType_Unexposed && + (hacky_parse_associated_type(self.spelling()) || + hacky_parse_associated_type( + self.canonical_type().spelling(), + )) + } +} + +/// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its +/// cursor is the canonical declaration for its type. If you have a +/// `CanonicalTypeDeclaration` instance, you know for sure that the type and +/// cursor match up in a canonical declaration relationship, and it simply +/// cannot be otherwise. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct CanonicalTypeDeclaration(Type, Cursor); + +impl CanonicalTypeDeclaration { + /// Get the type. + pub(crate) fn ty(&self) -> &Type { + &self.0 + } + + /// Get the type's canonical declaration cursor. + pub(crate) fn cursor(&self) -> &Cursor { + &self.1 + } +} + +/// An iterator for a type's template arguments. +pub(crate) struct TypeTemplateArgIterator { + x: CXType, + length: u32, + index: u32, +} + +impl Iterator for TypeTemplateArgIterator { + type Item = Type; + fn next(&mut self) -> Option { + if self.index < self.length { + let idx = self.index as c_uint; + self.index += 1; + Some(Type { + x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) }, + }) + } else { + None + } + } +} + +impl ExactSizeIterator for TypeTemplateArgIterator { + fn len(&self) -> usize { + assert!(self.index <= self.length); + (self.length - self.index) as usize + } +} + +/// A `SourceLocation` is a file, line, column, and byte offset location for +/// some source text. +pub(crate) struct SourceLocation { + x: CXSourceLocation, +} + +impl SourceLocation { + /// Get the (file, line, column, byte offset) tuple for this source + /// location. + pub(crate) fn location(&self) -> (File, usize, usize, usize) { + unsafe { + let mut file = mem::zeroed(); + let mut line = 0; + let mut col = 0; + let mut off = 0; + clang_getFileLocation( + self.x, &mut file, &mut line, &mut col, &mut off, + ); + (File { x: file }, line as usize, col as usize, off as usize) + } + } +} + +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}") + } else { + "builtin definitions".fmt(f) + } + } +} + +impl fmt::Debug for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{self}") + } +} + +/// A comment in the source text. +/// +/// Comments are sort of parsed by Clang, and have a tree structure. +pub(crate) struct Comment { + x: CXComment, +} + +impl Comment { + /// What kind of comment is this? + pub(crate) fn kind(&self) -> CXCommentKind { + unsafe { clang_Comment_getKind(self.x) } + } + + /// Get this comment's children comment + pub(crate) fn get_children(&self) -> CommentChildrenIterator { + CommentChildrenIterator { + parent: self.x, + length: unsafe { clang_Comment_getNumChildren(self.x) }, + index: 0, + } + } + + /// Given that this comment is the start or end of an HTML tag, get its tag + /// name. + pub(crate) fn get_tag_name(&self) -> String { + unsafe { cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) } + } + + /// Given that this comment is an HTML start tag, get its attributes. + pub(crate) fn get_tag_attrs(&self) -> CommentAttributesIterator { + CommentAttributesIterator { + x: self.x, + length: unsafe { clang_HTMLStartTag_getNumAttrs(self.x) }, + index: 0, + } + } +} + +/// An iterator for a comment's children +pub(crate) struct CommentChildrenIterator { + parent: CXComment, + length: c_uint, + index: c_uint, +} + +impl Iterator for CommentChildrenIterator { + type Item = Comment; + fn next(&mut self) -> Option { + if self.index < self.length { + let idx = self.index; + self.index += 1; + Some(Comment { + x: unsafe { clang_Comment_getChild(self.parent, idx) }, + }) + } else { + None + } + } +} + +/// An HTML start tag comment attribute +pub(crate) struct CommentAttribute { + /// HTML start tag attribute name + pub(crate) name: String, + /// HTML start tag attribute value + pub(crate) value: String, +} + +/// An iterator for a comment's attributes +pub(crate) struct CommentAttributesIterator { + x: CXComment, + length: c_uint, + index: c_uint, +} + +impl Iterator for CommentAttributesIterator { + type Item = CommentAttribute; + fn next(&mut self) -> Option { + if self.index < self.length { + let idx = self.index; + self.index += 1; + Some(CommentAttribute { + name: unsafe { + cxstring_into_string(clang_HTMLStartTag_getAttrName( + self.x, idx, + )) + }, + value: unsafe { + cxstring_into_string(clang_HTMLStartTag_getAttrValue( + self.x, idx, + )) + }, + }) + } else { + None + } + } +} + +/// A source file. +pub(crate) struct File { + x: CXFile, +} + +impl File { + /// Get the name of this source file. + pub(crate) fn name(&self) -> Option { + if self.x.is_null() { + return None; + } + Some(unsafe { cxstring_into_string(clang_getFileName(self.x)) }) + } +} + +fn cxstring_to_string_leaky(s: CXString) -> String { + if s.data.is_null() { + return String::new(); + } + let c_str = unsafe { CStr::from_ptr(clang_getCString(s)) }; + c_str.to_string_lossy().into_owned() +} + +fn cxstring_into_string(s: CXString) -> String { + let ret = cxstring_to_string_leaky(s); + unsafe { clang_disposeString(s) }; + ret +} + +/// An `Index` is an environment for a set of translation units that will +/// typically end up linked together in one final binary. +pub(crate) struct Index { + x: CXIndex, +} + +impl Index { + /// Construct a new `Index`. + /// + /// The `pch` parameter controls whether declarations in pre-compiled + /// headers are included when enumerating a translation unit's "locals". + /// + /// The `diag` parameter controls whether debugging diagnostics are enabled. + pub(crate) fn new(pch: bool, diag: bool) -> Index { + unsafe { + Index { + x: clang_createIndex(c_int::from(pch), c_int::from(diag)), + } + } + } +} + +impl fmt::Debug for Index { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "Index {{ }}") + } +} + +impl Drop for Index { + fn drop(&mut self) { + unsafe { + clang_disposeIndex(self.x); + } + } +} + +/// A translation unit (or "compilation unit"). +pub(crate) struct TranslationUnit { + x: CXTranslationUnit, +} + +impl fmt::Debug for TranslationUnit { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "TranslationUnit {{ }}") + } +} + +impl TranslationUnit { + /// Parse a source file into a translation unit. + pub(crate) fn parse( + ix: &Index, + file: &str, + cmd_args: &[Box], + unsaved: &[UnsavedFile], + opts: CXTranslationUnit_Flags, + ) -> Option { + let fname = CString::new(file).unwrap(); + let _c_args: Vec = cmd_args + .iter() + .map(|s| CString::new(s.as_bytes()).unwrap()) + .collect(); + let c_args: Vec<*const c_char> = + _c_args.iter().map(|s| s.as_ptr()).collect(); + let mut c_unsaved: Vec = + unsaved.iter().map(|f| f.x).collect(); + let tu = unsafe { + clang_parseTranslationUnit( + ix.x, + fname.as_ptr(), + c_args.as_ptr(), + c_args.len() as c_int, + c_unsaved.as_mut_ptr(), + c_unsaved.len() as c_uint, + opts, + ) + }; + if tu.is_null() { + None + } else { + Some(TranslationUnit { x: tu }) + } + } + + /// Get the Clang diagnostic information associated with this translation + /// unit. + pub(crate) fn diags(&self) -> Vec { + unsafe { + let num = clang_getNumDiagnostics(self.x) as usize; + let mut diags = vec![]; + for i in 0..num { + diags.push(Diagnostic { + x: clang_getDiagnostic(self.x, i as c_uint), + }); + } + diags + } + } + + /// Get a cursor pointing to the root of this translation unit's AST. + pub(crate) fn cursor(&self) -> Cursor { + unsafe { + Cursor { + x: clang_getTranslationUnitCursor(self.x), + } + } + } + + /// Save a translation unit to the given file. + pub(crate) fn save(&mut self, file: &str) -> Result<(), CXSaveError> { + let Ok(file) = CString::new(file) else { + return Err(CXSaveError_Unknown); + }; + let ret = unsafe { + clang_saveTranslationUnit( + self.x, + file.as_ptr(), + clang_defaultSaveOptions(self.x), + ) + }; + if ret != 0 { + Err(ret) + } else { + Ok(()) + } + } + + /// Is this the null translation unit? + pub(crate) fn is_null(&self) -> bool { + self.x.is_null() + } +} + +impl Drop for TranslationUnit { + fn drop(&mut self) { + unsafe { + clang_disposeTranslationUnit(self.x); + } + } +} + +/// Translation unit used for macro fallback parsing +pub(crate) struct FallbackTranslationUnit { + file_path: String, + pch_path: String, + idx: Box, + tu: TranslationUnit, +} + +impl fmt::Debug for FallbackTranslationUnit { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "FallbackTranslationUnit {{ }}") + } +} + +impl FallbackTranslationUnit { + /// Create a new fallback translation unit + pub(crate) fn new( + file: String, + pch_path: String, + c_args: &[Box], + ) -> Option { + // Create empty file + OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(&file) + .ok()?; + + let f_index = Box::new(Index::new(true, false)); + let f_translation_unit = TranslationUnit::parse( + &f_index, + &file, + c_args, + &[], + CXTranslationUnit_None, + )?; + Some(FallbackTranslationUnit { + file_path: file, + pch_path, + tu: f_translation_unit, + idx: f_index, + }) + } + + /// Get reference to underlying translation unit. + pub(crate) fn translation_unit(&self) -> &TranslationUnit { + &self.tu + } + + /// Reparse a translation unit. + pub(crate) fn reparse( + &mut self, + unsaved_contents: &str, + ) -> Result<(), CXErrorCode> { + let unsaved = &[UnsavedFile::new(&self.file_path, unsaved_contents)]; + let mut c_unsaved: Vec = + unsaved.iter().map(|f| f.x).collect(); + let ret = unsafe { + clang_reparseTranslationUnit( + self.tu.x, + unsaved.len() as c_uint, + c_unsaved.as_mut_ptr(), + clang_defaultReparseOptions(self.tu.x), + ) + }; + if ret != 0 { + Err(ret) + } else { + Ok(()) + } + } +} + +impl Drop for FallbackTranslationUnit { + fn drop(&mut self) { + let _ = std::fs::remove_file(&self.file_path); + let _ = std::fs::remove_file(&self.pch_path); + } +} + +/// A diagnostic message generated while parsing a translation unit. +pub(crate) struct Diagnostic { + x: CXDiagnostic, +} + +impl Diagnostic { + /// Format this diagnostic message as a string, using the given option bit + /// flags. + pub(crate) fn format(&self) -> String { + unsafe { + let opts = clang_defaultDiagnosticDisplayOptions(); + cxstring_into_string(clang_formatDiagnostic(self.x, opts)) + } + } + + /// What is the severity of this diagnostic message? + pub(crate) fn severity(&self) -> CXDiagnosticSeverity { + unsafe { clang_getDiagnosticSeverity(self.x) } + } +} + +impl Drop for Diagnostic { + /// Destroy this diagnostic message. + fn drop(&mut self) { + unsafe { + clang_disposeDiagnostic(self.x); + } + } +} + +/// A file which has not been saved to disk. +pub(crate) struct UnsavedFile { + x: CXUnsavedFile, + /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in + /// `CXUnsavedFile`. + pub(crate) name: CString, + contents: CString, +} + +impl UnsavedFile { + /// Construct a new unsaved file with the given `name` and `contents`. + pub(crate) fn new(name: &str, contents: &str) -> UnsavedFile { + let name = CString::new(name.as_bytes()).unwrap(); + let contents = CString::new(contents.as_bytes()).unwrap(); + let x = CXUnsavedFile { + Filename: name.as_ptr(), + Contents: contents.as_ptr(), + Length: contents.as_bytes().len() as c_ulong, + }; + UnsavedFile { x, name, contents } + } +} + +impl fmt::Debug for UnsavedFile { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!( + fmt, + "UnsavedFile(name: {:?}, contents: {:?})", + self.name, self.contents + ) + } +} + +/// Convert a cursor kind into a static string. +pub(crate) fn kind_to_str(x: CXCursorKind) -> String { + unsafe { cxstring_into_string(clang_getCursorKindSpelling(x)) } +} + +/// Convert a type kind to a static string. +pub(crate) fn type_to_str(x: CXTypeKind) -> String { + unsafe { cxstring_into_string(clang_getTypeKindSpelling(x)) } +} + +/// Dump the Clang AST to stdout for debugging purposes. +pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { + fn print_indent>(depth: isize, s: S) { + for _ in 0..depth { + print!(" "); + } + println!("{}", s.as_ref()); + } + + fn print_cursor>(depth: isize, prefix: S, c: &Cursor) { + let prefix = prefix.as_ref(); + print_indent( + depth, + format!(" {prefix}kind = {}", kind_to_str(c.kind())), + ); + print_indent( + depth, + format!(" {prefix}spelling = \"{}\"", c.spelling()), + ); + print_indent(depth, format!(" {prefix}location = {}", c.location())); + print_indent( + depth, + format!(" {prefix}is-definition? {}", c.is_definition()), + ); + print_indent( + depth, + format!(" {prefix}is-declaration? {}", c.is_declaration()), + ); + print_indent( + depth, + format!( + " {prefix}is-inlined-function? {}", + c.is_inlined_function() + ), + ); + + let templ_kind = c.template_kind(); + if templ_kind != CXCursor_NoDeclFound { + print_indent( + depth, + format!(" {prefix}template-kind = {}", kind_to_str(templ_kind)), + ); + } + if let Some(usr) = c.usr() { + print_indent(depth, format!(" {prefix}usr = \"{usr}\"")); + } + if let Ok(num) = c.num_args() { + print_indent(depth, format!(" {prefix}number-of-args = {num}")); + } + if let Some(num) = c.num_template_args() { + print_indent( + depth, + format!(" {prefix}number-of-template-args = {num}"), + ); + } + + if c.is_bit_field() { + let width = match c.bit_width() { + Some(w) => w.to_string(), + None => "".to_string(), + }; + print_indent(depth, format!(" {prefix}bit-width = {width}")); + } + + if let Some(ty) = c.enum_type() { + print_indent( + depth, + format!(" {prefix}enum-type = {}", type_to_str(ty.kind())), + ); + } + if let Some(val) = c.enum_val_signed() { + print_indent(depth, format!(" {prefix}enum-val = {val}")); + } + if let Some(ty) = c.typedef_type() { + print_indent( + depth, + format!(" {prefix}typedef-type = {}", type_to_str(ty.kind())), + ); + } + if let Some(ty) = c.ret_type() { + print_indent( + depth, + format!(" {prefix}ret-type = {}", type_to_str(ty.kind())), + ); + } + + if let Some(refd) = c.referenced() { + if refd != *c { + println!(); + print_cursor( + depth, + String::from(prefix) + "referenced.", + &refd, + ); + } + } + + let canonical = c.canonical(); + if canonical != *c { + println!(); + print_cursor( + depth, + String::from(prefix) + "canonical.", + &canonical, + ); + } + + if let Some(specialized) = c.specialized() { + if specialized != *c { + println!(); + print_cursor( + depth, + String::from(prefix) + "specialized.", + &specialized, + ); + } + } + + if let Some(parent) = c.fallible_semantic_parent() { + println!(); + print_cursor( + depth, + String::from(prefix) + "semantic-parent.", + &parent, + ); + } + } + + fn print_type>(depth: isize, prefix: S, ty: &Type) { + let prefix = prefix.as_ref(); + + let kind = ty.kind(); + print_indent(depth, format!(" {prefix}kind = {}", type_to_str(kind))); + if kind == CXType_Invalid { + return; + } + + print_indent(depth, format!(" {prefix}cconv = {}", ty.call_conv())); + + print_indent( + depth, + format!(" {prefix}spelling = \"{}\"", ty.spelling()), + ); + let num_template_args = + unsafe { clang_Type_getNumTemplateArguments(ty.x) }; + if num_template_args >= 0 { + print_indent( + depth, + format!( + " {prefix}number-of-template-args = {num_template_args}" + ), + ); + } + if let Some(num) = ty.num_elements() { + print_indent(depth, format!(" {prefix}number-of-elements = {num}")); + } + print_indent( + depth, + format!(" {prefix}is-variadic? {}", ty.is_variadic()), + ); + + let canonical = ty.canonical_type(); + if canonical != *ty { + println!(); + print_type(depth, String::from(prefix) + "canonical.", &canonical); + } + + if let Some(pointee) = ty.pointee_type() { + if pointee != *ty { + println!(); + print_type(depth, String::from(prefix) + "pointee.", &pointee); + } + } + + if let Some(elem) = ty.elem_type() { + if elem != *ty { + println!(); + print_type(depth, String::from(prefix) + "elements.", &elem); + } + } + + if let Some(ret) = ty.ret_type() { + if ret != *ty { + println!(); + print_type(depth, String::from(prefix) + "return.", &ret); + } + } + + let named = ty.named(); + if named != *ty && named.is_valid() { + println!(); + print_type(depth, String::from(prefix) + "named.", &named); + } + } + + print_indent(depth, "("); + print_cursor(depth, "", c); + + println!(); + let ty = c.cur_type(); + print_type(depth, "type.", &ty); + + let declaration = ty.declaration(); + if declaration != *c && declaration.kind() != CXCursor_NoDeclFound { + println!(); + print_cursor(depth, "type.declaration.", &declaration); + } + + // Recurse. + let mut found_children = false; + c.visit(|s| { + if !found_children { + println!(); + found_children = true; + } + ast_dump(&s, depth + 1) + }); + + print_indent(depth, ")"); + + CXChildVisit_Continue +} + +/// Try to extract the clang version to a string +pub(crate) fn extract_clang_version() -> String { + unsafe { cxstring_into_string(clang_getClangVersion()) } +} + +/// A wrapper for the result of evaluating an expression. +#[derive(Debug)] +pub(crate) struct EvalResult { + x: CXEvalResult, + ty: Type, +} + +impl EvalResult { + /// Evaluate `cursor` and return the result. + pub(crate) fn new(cursor: Cursor) -> Option { + // Work around https://bugs.llvm.org/show_bug.cgi?id=42532, see: + // * https://github.com/rust-lang/rust-bindgen/issues/283 + // * https://github.com/rust-lang/rust-bindgen/issues/1590 + { + let mut found_cant_eval = false; + cursor.visit(|c| { + if c.kind() == CXCursor_TypeRef && + c.cur_type().canonical_type().kind() == CXType_Unexposed + { + found_cant_eval = true; + return CXChildVisit_Break; + } + + CXChildVisit_Recurse + }); + + if found_cant_eval { + return None; + } + } + Some(EvalResult { + x: unsafe { clang_Cursor_Evaluate(cursor.x) }, + ty: cursor.cur_type().canonical_type(), + }) + } + + fn kind(&self) -> CXEvalResultKind { + unsafe { clang_EvalResult_getKind(self.x) } + } + + /// Try to get back the result as a double. + pub(crate) fn as_double(&self) -> Option { + match self.kind() { + CXEval_Float => { + Some(unsafe { clang_EvalResult_getAsDouble(self.x) }) + } + _ => None, + } + } + + /// Try to get back the result as an integer. + pub(crate) fn as_int(&self) -> Option { + if self.kind() != CXEval_Int { + return None; + } + + if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 { + let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) }; + 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); + } + + let value = unsafe { clang_EvalResult_getAsLongLong(self.x) }; + if value > i64::MAX as c_longlong { + return None; + } + if value < i64::MIN as c_longlong { + return None; + } + #[allow(clippy::unnecessary_cast)] + Some(value as i64) + } + + /// Evaluates the expression as a literal string, that may or may not be + /// valid utf-8. + pub(crate) fn as_literal_string(&self) -> Option> { + if self.kind() != CXEval_StrLiteral { + return None; + } + + let char_ty = self.ty.pointee_type().or_else(|| self.ty.elem_type())?; + match char_ty.kind() { + CXType_Char_S | CXType_SChar | CXType_Char_U | CXType_UChar => { + let ret = unsafe { + CStr::from_ptr(clang_EvalResult_getAsStr(self.x)) + }; + Some(ret.to_bytes().to_vec()) + } + // FIXME: Support generating these. + CXType_Char16 => None, + CXType_Char32 => None, + CXType_WChar => None, + _ => None, + } + } +} + +impl Drop for EvalResult { + fn drop(&mut self) { + unsafe { clang_EvalResult_dispose(self.x) }; + } +} +/// ABI kinds as defined in +/// +#[derive(Debug, Eq, PartialEq, Copy, Clone)] +pub(crate) enum ABIKind { + /// All the regular targets like Linux, Mac, WASM, etc. implement the Itanium ABI + GenericItanium, + /// The ABI used when compiling for the MSVC target + Microsoft, +} + +/// Target information obtained from libclang. +#[derive(Debug)] +pub(crate) struct TargetInfo { + /// The target triple. + pub(crate) triple: String, + /// The width of the pointer _in bits_. + pub(crate) pointer_width: usize, + /// The ABI of the target + pub(crate) abi: ABIKind, +} + +impl TargetInfo { + /// Tries to obtain target information from libclang. + pub(crate) fn new(tu: &TranslationUnit) -> Self { + let triple; + let pointer_width; + unsafe { + let ti = clang_getTranslationUnitTargetInfo(tu.x); + triple = cxstring_into_string(clang_TargetInfo_getTriple(ti)); + pointer_width = clang_TargetInfo_getPointerWidth(ti); + clang_TargetInfo_dispose(ti); + } + assert!(pointer_width > 0); + assert_eq!(pointer_width % 8, 0); + + let abi = if triple.contains("msvc") { + ABIKind::Microsoft + } else { + ABIKind::GenericItanium + }; + + TargetInfo { + triple, + pointer_width: pointer_width as usize, + abi, + } + } +} diff --git a/bindgen/codegen/bitfield_unit.rs b/bindgen/codegen/bitfield_unit.rs new file mode 100644 index 0000000000..8be311e311 --- /dev/null +++ b/bindgen/codegen/bitfield_unit.rs @@ -0,0 +1,195 @@ +#[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) + }; + } + } +} diff --git a/src/codegen/bitfield_unit_tests.rs b/bindgen/codegen/bitfield_unit_tests.rs similarity index 97% rename from src/codegen/bitfield_unit_tests.rs rename to bindgen/codegen/bitfield_unit_tests.rs index e143e4ea78..ead0ffec0c 100644 --- a/src/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 new file mode 100644 index 0000000000..76f3805795 --- /dev/null +++ b/bindgen/codegen/dyngen.rs @@ -0,0 +1,258 @@ +use crate::codegen; +use crate::ir::context::BindgenContext; +use crate::ir::function::ClangAbi; +use proc_macro2::{Ident, TokenStream}; + +/// Used to build the output tokens for dynamic bindings. +#[derive(Default)] +pub(crate) struct DynamicItems { + /// Tracks the tokens that will appears inside the library struct -- e.g.: + /// ```ignore + /// struct Lib { + /// __library: ::libloading::Library, + /// pub x: Result, // <- tracks these + /// ... + /// } + /// ``` + struct_members: Vec, + + /// Tracks the tokens that will appear inside the library struct's implementation, e.g.: + /// + /// ```ignore + /// impl Lib { + /// ... + /// pub unsafe fn foo(&self, ...) { // <- tracks these + /// ... + /// } + /// } + /// ``` + struct_implementation: Vec, + + /// Tracks the initialization of the fields inside the `::new` constructor of the library + /// struct, e.g.: + /// ```ignore + /// impl Lib { + /// + /// pub unsafe fn new

(path: P) -> Result + /// where + /// P: AsRef<::std::ffi::OsStr>, + /// { + /// ... + /// let foo = __library.get(...) ...; // <- tracks these + /// ... + /// } + /// + /// ... + /// } + /// ``` + constructor_inits: Vec, + + /// Tracks the information that is passed to the library struct at the end of the `::new` + /// constructor, e.g.: + /// ```ignore + /// impl LibFoo { + /// pub unsafe fn new

(path: P) -> Result + /// where + /// P: AsRef<::std::ffi::OsStr>, + /// { + /// ... + /// Ok(LibFoo { + /// __library: __library, + /// foo, + /// bar, // <- tracks these + /// ... + /// }) + /// } + /// } + /// ``` + init_fields: Vec, +} + +impl DynamicItems { + pub(crate) fn new() -> Self { + Self::default() + } + + pub(crate) fn get_tokens( + &self, + lib_ident: &Ident, + ctx: &BindgenContext, + ) -> 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 { + quote!(Self::from_library(library)) + }; + + quote! { + pub struct #lib_ident { + __library: ::libloading::Library, + #(#struct_members)* + } + + impl #lib_ident { + pub unsafe fn new

*/ + /// Baz = 0, + /// }; + /// ``` + /// + /// In that case, bindgen will generate a constant for `Bar` instead of + /// `Baz`. + constify_enum_variant: bool, + /// List of explicit derives for this type. + derives: Vec, + /// List of explicit attributes for this type. + attributes: Vec, +} + +fn parse_accessor(s: &str) -> FieldAccessorKind { + match s { + "false" => FieldAccessorKind::None, + "unsafe" => FieldAccessorKind::Unsafe, + "immutable" => FieldAccessorKind::Immutable, + _ => FieldAccessorKind::Regular, + } +} + +impl Annotations { + /// Construct new annotations for the given cursor and its bindgen comments + /// (if any). + pub(crate) fn new(cursor: &clang::Cursor) -> Option { + let mut anno = Annotations::default(); + let mut matched_one = false; + anno.parse(&cursor.comment(), &mut matched_one); + + if matched_one { + Some(anno) + } else { + None + } + } + + /// Should this type be hidden? + pub(crate) fn hide(&self) -> bool { + self.hide + } + + /// Should this type be opaque? + pub(crate) fn opaque(&self) -> bool { + self.opaque + } + + /// For a given type, indicates the type it should replace. + /// + /// For example, in the following code: + /// + /// ```cpp + /// + /// /**
*/ + /// struct Foo { int x; }; + /// + /// struct Bar { char foo; }; + /// ``` + /// + /// the generated code would look something like: + /// + /// ``` + /// /**
*/ + /// struct Bar { + /// x: ::std::os::raw::c_int, + /// }; + /// ``` + /// + /// That is, code for `Foo` is used to generate `Bar`. + pub(crate) fn use_instead_of(&self) -> Option<&[String]> { + self.use_instead_of.as_deref() + } + + /// The list of derives that have been specified in this annotation. + pub(crate) fn derives(&self) -> &[String] { + &self.derives + } + + /// The list of attributes that have been specified in this annotation. + pub(crate) fn attributes(&self) -> &[String] { + &self.attributes + } + + /// Should we avoid implementing the `Copy` trait? + pub(crate) fn disallow_copy(&self) -> bool { + self.disallow_copy + } + + /// Should we avoid implementing the `Debug` trait? + pub(crate) fn disallow_debug(&self) -> bool { + self.disallow_debug + } + + /// Should we avoid implementing the `Default` trait? + pub(crate) fn disallow_default(&self) -> bool { + self.disallow_default + } + + /// Should this type get a `#[must_use]` annotation? + pub(crate) fn must_use_type(&self) -> bool { + self.must_use_type + } + + /// What kind of accessors should we provide for this type's fields? + pub(crate) fn visibility_kind(&self) -> Option { + self.visibility_kind + } + + /// What kind of accessors should we provide for this type's fields? + pub(crate) fn accessor_kind(&self) -> Option { + self.accessor_kind + } + + fn parse(&mut self, comment: &clang::Comment, matched: &mut bool) { + use clang_sys::CXComment_HTMLStartTag; + if comment.kind() == CXComment_HTMLStartTag && + comment.get_tag_name() == "div" && + comment + .get_tag_attrs() + .next() + .is_some_and(|attr| attr.name == "rustbindgen") + { + *matched = true; + for attr in comment.get_tag_attrs() { + match attr.name.as_str() { + "opaque" => self.opaque = true, + "hide" => self.hide = true, + "nocopy" => self.disallow_copy = true, + "nodebug" => self.disallow_debug = true, + "nodefault" => self.disallow_default = true, + "mustusetype" => self.must_use_type = true, + "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::Public) + } else { + Some(FieldVisibilityKind::Private) + }; + } + "accessor" => { + self.accessor_kind = Some(parse_accessor(&attr.value)); + } + "constant" => self.constify_enum_variant = true, + _ => {} + } + } + } + + for child in comment.get_children() { + self.parse(&child, matched); + } + } + + /// Returns whether we've parsed a "constant" attribute. + pub(crate) fn constify_enum_variant(&self) -> bool { + self.constify_enum_variant + } +} diff --git a/bindgen/ir/comment.rs b/bindgen/ir/comment.rs new file mode 100644 index 0000000000..a4ba320186 --- /dev/null +++ b/bindgen/ir/comment.rs @@ -0,0 +1,100 @@ +//! Utilities for manipulating C/C++ comments. + +/// The type of a comment. +#[derive(Debug, PartialEq, Eq)] +enum Kind { + /// A `///` comment, or something of the like. + /// All lines in a comment should start with the same symbol. + SingleLines, + /// A `/**` comment, where each other line can start with `*` and the + /// entire block ends with `*/`. + MultiLine, +} + +/// Preprocesses a C/C++ comment so that it is a valid Rust comment. +pub(crate) fn preprocess(comment: &str) -> String { + match kind(comment) { + Some(Kind::SingleLines) => preprocess_single_lines(comment), + Some(Kind::MultiLine) => preprocess_multi_line(comment), + None => comment.to_owned(), + } +} + +/// Gets the kind of the doc comment, if it is one. +fn kind(comment: &str) -> Option { + if comment.starts_with("/*") { + Some(Kind::MultiLine) + } else if comment.starts_with("//") { + Some(Kind::SingleLines) + } else { + None + } +} + +/// Preprocesses multiple single line comments. +/// +/// Handles lines starting with both `//` and `///`. +fn preprocess_single_lines(comment: &str) -> String { + debug_assert!(comment.starts_with("//"), "comment is not single line"); + + let lines: Vec<_> = comment + .lines() + .map(|l| l.trim().trim_start_matches('/')) + .collect(); + lines.join("\n") +} + +fn preprocess_multi_line(comment: &str) -> String { + let comment = comment + .trim_start_matches('/') + .trim_end_matches('/') + .trim_end_matches('*'); + + // Strip any potential `*` characters preceding each line. + let mut lines: Vec<_> = comment + .lines() + .map(|line| line.trim().trim_start_matches('*').trim_start_matches('!')) + .skip_while(|line| line.trim().is_empty()) // Skip the first empty lines. + .collect(); + + // Remove the trailing line corresponding to the `*/`. + if lines.last().is_some_and(|l| l.trim().is_empty()) { + lines.pop(); + } + + lines.join("\n") +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn picks_up_single_and_multi_line_doc_comments() { + assert_eq!(kind("/// hello"), Some(Kind::SingleLines)); + assert_eq!(kind("/** world */"), Some(Kind::MultiLine)); + } + + #[test] + fn processes_single_lines_correctly() { + assert_eq!(preprocess("///"), ""); + assert_eq!(preprocess("/// hello"), " hello"); + assert_eq!(preprocess("// hello"), " hello"); + assert_eq!(preprocess("// hello"), " hello"); + } + + #[test] + fn processes_multi_lines_correctly() { + assert_eq!(preprocess("/**/"), ""); + + assert_eq!( + preprocess("/** hello \n * world \n * foo \n */"), + " hello\n world\n foo" + ); + + assert_eq!( + preprocess("/**\nhello\n*world\n*foo\n*/"), + "hello\nworld\nfoo" + ); + } +} diff --git a/src/ir/comp.rs b/bindgen/ir/comp.rs similarity index 85% rename from src/ir/comp.rs rename to bindgen/ir/comp.rs index a221e52074..c67f9a2597 100644 --- a/src/ir/comp.rs +++ b/bindgen/ir/comp.rs @@ -1,5 +1,7 @@ //! Compound types (unions and structs) in our intermediate representation. +use itertools::Itertools; + use super::analysis::Sizedness; use super::annotations::Annotations; use super::context::{BindgenContext, FunctionId, ItemId, TypeId, VarId}; @@ -10,18 +12,18 @@ 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::{ClangItemParser, ParseError}; +use crate::parse::ParseError; use crate::HashMap; -use peeking_take_while::PeekableExt; +use crate::NonCopyUnionStyle; use std::cmp; use std::io; use std::mem; /// The kind of compound type. -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum CompKind { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum CompKind { /// A struct. Struct, /// A union. @@ -29,8 +31,8 @@ pub enum CompKind { } /// The kind of C++ method. -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum MethodKind { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum MethodKind { /// A constructor. We represent it as method for convenience, to avoid code /// duplication. Constructor, @@ -54,18 +56,16 @@ pub enum MethodKind { impl MethodKind { /// Is this a destructor method? - pub fn is_destructor(&self) -> bool { - match *self { - MethodKind::Destructor | MethodKind::VirtualDestructor { .. } => { - true - } - _ => false, - } + pub(crate) fn is_destructor(self) -> bool { + matches!( + self, + MethodKind::Destructor | MethodKind::VirtualDestructor { .. } + ) } /// Is this a pure virtual method? - pub 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, @@ -75,7 +75,7 @@ impl MethodKind { /// A struct representing a C++ method, either static, normal, or virtual. #[derive(Debug)] -pub struct Method { +pub(crate) struct Method { kind: MethodKind, /// The signature of the method. Take into account this is not a `Type` /// item, but a `Function` one. @@ -87,7 +87,7 @@ pub struct Method { impl Method { /// Construct a new `Method`. - pub fn new( + pub(crate) fn new( kind: MethodKind, signature: FunctionId, is_const: bool, @@ -100,17 +100,17 @@ impl Method { } /// What kind of method is this? - pub fn kind(&self) -> MethodKind { + pub(crate) fn kind(&self) -> MethodKind { self.kind } /// Is this a constructor? - pub fn is_constructor(&self) -> bool { + pub(crate) fn is_constructor(&self) -> bool { self.kind == MethodKind::Constructor } /// Is this a virtual method? - pub fn is_virtual(&self) -> bool { + pub(crate) fn is_virtual(&self) -> bool { matches!( self.kind, MethodKind::Virtual { .. } | MethodKind::VirtualDestructor { .. } @@ -118,23 +118,23 @@ impl Method { } /// Is this a static method? - pub fn is_static(&self) -> bool { + pub(crate) fn is_static(&self) -> bool { self.kind == MethodKind::Static } - /// Get the id for the `Function` signature for this method. - pub fn signature(&self) -> FunctionId { + /// Get the ID for the `Function` signature for this method. + pub(crate) fn signature(&self) -> FunctionId { self.signature } /// Is this a const qualified method? - pub fn is_const(&self) -> bool { + pub(crate) fn is_const(&self) -> bool { self.is_const } } /// Methods common to the various field types. -pub trait FieldMethods { +pub(crate) trait FieldMethods { /// Get the name of this field. fn name(&self) -> Option<&str>; @@ -147,7 +147,7 @@ pub trait FieldMethods { /// If this is a bitfield, how many bits does it need? fn bitfield_width(&self) -> Option; - /// Is this feild declared public? + /// Is this field declared public? fn is_public(&self) -> bool; /// Get the annotations for this field. @@ -162,7 +162,7 @@ pub trait FieldMethods { /// 2.4.II.1 in the Itanium C++ /// ABI](http://itanium-cxx-abi.github.io/cxx-abi/abi.html#class-types). #[derive(Debug)] -pub struct BitfieldUnit { +pub(crate) struct BitfieldUnit { nth: usize, layout: Layout, bitfields: Vec, @@ -172,24 +172,24 @@ impl BitfieldUnit { /// Get the 1-based index of this bitfield unit within its containing /// struct. Useful for generating a Rust struct's field name for this unit /// of bitfields. - pub fn nth(&self) -> usize { + pub(crate) fn nth(&self) -> usize { self.nth } /// Get the layout within which these bitfields reside. - pub fn layout(&self) -> Layout { + pub(crate) fn layout(&self) -> Layout { self.layout } /// Get the bitfields within this unit. - pub fn bitfields(&self) -> &[Bitfield] { + pub(crate) fn bitfields(&self) -> &[Bitfield] { &self.bitfields } } /// A struct representing a C++ field. #[derive(Debug)] -pub enum Field { +pub(crate) enum Field { /// A normal data member. DataMember(FieldData), @@ -199,7 +199,7 @@ pub enum Field { impl Field { /// Get this field's layout. - pub fn layout(&self, ctx: &BindgenContext) -> Option { + pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option { match *self { Field::Bitfields(BitfieldUnit { layout, .. }) => Some(layout), Field::DataMember(ref data) => { @@ -308,7 +308,7 @@ impl DotAttributes for Bitfield { /// A logical bitfield within some physical bitfield allocation unit. #[derive(Debug)] -pub struct Bitfield { +pub(crate) struct Bitfield { /// Index of the bit within this bitfield's allocation unit where this /// bitfield's bits begin. offset_into_unit: usize, @@ -342,27 +342,12 @@ impl Bitfield { /// Get the index of the bit within this bitfield's allocation unit where /// this bitfield begins. - pub fn offset_into_unit(&self) -> usize { + pub(crate) fn offset_into_unit(&self) -> usize { self.offset_into_unit } - /// Get the mask value that when &'ed with this bitfield's allocation unit - /// produces this bitfield's value. - pub fn mask(&self) -> u64 { - use std::u64; - - let unoffseted_mask = - if self.width() as u64 == mem::size_of::() as u64 * 8 { - u64::MAX - } else { - (1u64 << self.width()) - 1u64 - }; - - unoffseted_mask << self.offset_into_unit() - } - /// Get the bit width of this bitfield. - pub fn width(&self) -> u32 { + pub(crate) fn width(&self) -> u32 { self.data.bitfield_width().unwrap() } @@ -370,13 +355,13 @@ impl Bitfield { /// /// Panics if called before assigning bitfield accessor names or if /// this bitfield have no name. - pub fn getter_name(&self) -> &str { + pub(crate) fn getter_name(&self) -> &str { assert!( self.name().is_some(), "`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", ) } @@ -385,13 +370,13 @@ impl Bitfield { /// /// Panics if called before assigning bitfield accessor names or if /// this bitfield have no name. - pub fn setter_name(&self) -> &str { + pub(crate) fn setter_name(&self) -> &str { assert!( self.name().is_some(), "`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", ) } @@ -575,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 { @@ -596,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 @@ -667,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 { @@ -684,9 +635,7 @@ where fields, bitfield_unit_count, unit_size_in_bits, - unit_align, bitfields_in_unit, - packed, ); } @@ -797,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"); @@ -818,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) => { @@ -840,6 +788,23 @@ impl CompFields { } } } + + /// Return the flex array member for the struct/class, if any. + fn flex_array_member(&self, ctx: &BindgenContext) -> Option { + let fields = match self { + CompFields::Before(_) => panic!("raw fields"), + CompFields::After { fields, .. } => fields, + CompFields::Error => return None, // panic? + }; + + match fields.last()? { + Field::Bitfields(..) => None, + Field::DataMember(FieldData { ty, .. }) => ctx + .resolve_type(*ty) + .is_incomplete_array(ctx) + .map(|item| item.expect_type_id(ctx)), + } + } } impl Trace for CompFields { @@ -867,7 +832,7 @@ impl Trace for CompFields { /// Common data shared across different field types. #[derive(Clone, Debug)] -pub struct FieldData { +pub(crate) struct FieldData { /// The name of the field, empty if it's an unnamed bitfield width. name: Option, @@ -922,7 +887,7 @@ impl FieldMethods for FieldData { /// The kind of inheritance a base class is using. #[derive(Clone, Debug, PartialEq, Eq)] -pub enum BaseKind { +pub(crate) enum BaseKind { /// Normal inheritance, like: /// /// ```cpp @@ -939,25 +904,25 @@ pub enum BaseKind { /// A base class. #[derive(Clone, Debug)] -pub struct Base { +pub(crate) struct Base { /// The type of this base class. - pub ty: TypeId, + pub(crate) ty: TypeId, /// The kind of inheritance we're doing. - pub kind: BaseKind, + pub(crate) kind: BaseKind, /// Name of the field in which this base should be stored. - pub field_name: String, - /// Whether this base is inherited from publically. - pub is_pub: bool, + pub(crate) field_name: String, + /// Whether this base is inherited from publicly. + pub(crate) is_pub: bool, } impl Base { /// Whether this base class is inheriting virtually. - pub fn is_virtual(&self) -> bool { + pub(crate) fn is_virtual(&self) -> bool { self.kind == BaseKind::Virtual } /// Whether this base class should have it's own field for storage. - pub fn requires_storage(&self, ctx: &BindgenContext) -> bool { + pub(crate) fn requires_storage(&self, ctx: &BindgenContext) -> bool { // Virtual bases are already taken into account by the vtable // pointer. // @@ -976,8 +941,8 @@ impl Base { true } - /// Whether this base is inherited from publically. - pub fn is_public(&self) -> bool { + /// Whether this base is inherited from publicly. + pub(crate) fn is_public(&self) -> bool { self.is_pub } } @@ -988,7 +953,7 @@ impl Base { /// of fields which also are associated with their own (potentially compound) /// type. #[derive(Debug)] -pub struct CompInfo { +pub(crate) struct CompInfo { /// Whether this is a struct or a union. kind: CompKind, @@ -1016,6 +981,7 @@ pub struct CompInfo { /// The inner types that were declared inside this class, in something like: /// + /// ```c++ /// class Foo { /// typedef int FooTy; /// struct Bar { @@ -1024,6 +990,7 @@ pub struct CompInfo { /// } /// /// static Foo::Bar const = {3}; + /// ``` inner_types: Vec, /// Set of static constants declared inside this class. @@ -1042,15 +1009,20 @@ pub 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 + /// evaluated (e.g. if it depends on a template parameter). We generate an + /// opaque type in this case. + has_unevaluable_bit_field_width: bool, + /// Whether we saw `__attribute__((packed))` on or within this type. packed_attr: bool, /// 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. @@ -1063,7 +1035,7 @@ pub struct CompInfo { impl CompInfo { /// Construct a new compound type. - pub fn new(kind: CompKind) -> Self { + pub(crate) fn new(kind: CompKind) -> Self { CompInfo { kind, fields: CompFields::default(), @@ -1078,6 +1050,7 @@ impl CompInfo { has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, + has_unevaluable_bit_field_width: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false, @@ -1091,8 +1064,8 @@ 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 - pub fn layout(&self, ctx: &BindgenContext) -> Option { + /// 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 { return None; @@ -1121,7 +1094,7 @@ impl CompInfo { } /// Get this type's set of fields. - pub fn fields(&self) -> &[Field] { + pub(crate) fn fields(&self) -> &[Field] { match self.fields { CompFields::Error => &[], CompFields::After { ref fields, .. } => fields, @@ -1131,6 +1104,14 @@ impl CompInfo { } } + /// Return the flex array member and its element type if any + pub(crate) fn flex_array_member( + &self, + ctx: &BindgenContext, + ) -> Option { + self.fields.flex_array_member(ctx) + } + fn has_fields(&self) -> bool { match self.fields { CompFields::Error => false, @@ -1147,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); @@ -1164,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 { @@ -1179,7 +1161,7 @@ impl CompInfo { /// Returns whether we have a too large bitfield unit, in which case we may /// not be able to derive some of the things we should be able to normally /// derive. - pub fn has_too_large_bitfield_unit(&self) -> bool { + pub(crate) fn has_too_large_bitfield_unit(&self) -> bool { if !self.has_bitfields() { return false; } @@ -1193,53 +1175,53 @@ impl CompInfo { /// Does this type have any template parameters that aren't types /// (e.g. int)? - pub fn has_non_type_template_params(&self) -> bool { + pub(crate) fn has_non_type_template_params(&self) -> bool { self.has_non_type_template_params } /// Do we see a virtual function during parsing? - /// Get the has_own_virtual_method boolean. - pub fn has_own_virtual_method(&self) -> bool { + /// Get the `has_own_virtual_method` boolean. + pub(crate) fn has_own_virtual_method(&self) -> bool { self.has_own_virtual_method } /// Did we see a destructor when parsing this type? - pub fn has_own_destructor(&self) -> bool { + pub(crate) fn has_own_destructor(&self) -> bool { self.has_destructor } /// Get this type's set of methods. - pub fn methods(&self) -> &[Method] { + pub(crate) fn methods(&self) -> &[Method] { &self.methods } /// Get this type's set of constructors. - pub fn constructors(&self) -> &[FunctionId] { + pub(crate) fn constructors(&self) -> &[FunctionId] { &self.constructors } /// Get this type's destructor. - pub fn destructor(&self) -> Option<(MethodKind, FunctionId)> { + pub(crate) fn destructor(&self) -> Option<(MethodKind, FunctionId)> { self.destructor } /// What kind of compound type is this? - pub fn kind(&self) -> CompKind { + pub(crate) fn kind(&self) -> CompKind { self.kind } /// Is this a union? - pub fn is_union(&self) -> bool { + pub(crate) fn is_union(&self) -> bool { self.kind() == CompKind::Union } /// The set of types that this one inherits from. - pub fn base_members(&self) -> &[Base] { + pub(crate) fn base_members(&self) -> &[Base] { &self.base_members } /// Construct a new compound type from a Clang type. - pub fn from_ty( + pub(crate) fn from_ty( potential_id: ItemId, ty: &clang::Type, location: Option, @@ -1262,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 = @@ -1317,7 +1299,21 @@ impl CompInfo { } } - let bit_width = cur.bit_width(); + let bit_width = if cur.is_bit_field() { + let width = cur.bit_width(); + + // Make opaque type if the bit width couldn't be + // evaluated. + if width.is_none() { + ci.has_unevaluable_bit_field_width = true; + return CXChildVisit_Break; + } + + width + } else { + None + }; + let field_type = Item::from_ty_or_ref( cur.cur_type(), cur, @@ -1403,8 +1399,7 @@ impl CompInfo { // A declaration of an union or a struct without name // could also be an unnamed field, unfortunately. - if cur.spelling().is_empty() && - cur.kind() != CXCursor_EnumDecl + if cur.is_anonymous() && cur.kind() != CXCursor_EnumDecl { let ty = cur.cur_type(); let public = cur.public_accessible(); @@ -1420,7 +1415,7 @@ impl CompInfo { } CXCursor_TemplateTypeParameter => { let param = Item::type_param(None, cur, ctx).expect( - "Item::type_param should't fail when pointing \ + "Item::type_param shouldn't fail when pointing \ at a TemplateTypeParameter", ); ci.template_params.push(param); @@ -1437,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); @@ -1445,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 | @@ -1585,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); } }) @@ -1593,23 +1587,23 @@ impl CompInfo { /// Get the set of types that were declared within this compound type /// (e.g. nested class definitions). - pub fn inner_types(&self) -> &[TypeId] { + pub(crate) fn inner_types(&self) -> &[TypeId] { &self.inner_types } /// Get the set of static variables declared within this compound type. - pub fn inner_vars(&self) -> &[VarId] { + pub(crate) fn inner_vars(&self) -> &[VarId] { &self.inner_vars } /// Have we found a field with an opaque type that could potentially mess up /// the layout of this compound type? - pub fn found_unknown_attr(&self) -> bool { + pub(crate) fn found_unknown_attr(&self) -> bool { self.found_unknown_attr } /// Is this compound type packed? - pub fn is_packed( + pub(crate) fn is_packed( &self, ctx: &BindgenContext, layout: Option<&Layout>, @@ -1638,45 +1632,81 @@ impl CompInfo { false } + /// Return true if a compound type is "naturally packed". This means we can exclude the + /// "packed" attribute without changing the layout. + /// This is useful for types that need an "align(N)" attribute since rustc won't compile + /// structs that have both of those attributes. + pub(crate) fn already_packed(&self, ctx: &BindgenContext) -> Option { + let mut total_size: usize = 0; + + for field in self.fields() { + let layout = field.layout(ctx)?; + + if layout.align != 0 && total_size % layout.align != 0 { + return Some(false); + } + + total_size += layout.size; + } + + Some(true) + } + /// Returns true if compound type has been forward declared - pub fn is_forward_declaration(&self) -> bool { + pub(crate) fn is_forward_declaration(&self) -> bool { self.is_forward_declaration } /// Compute this compound structure's bitfield allocation units. - pub fn compute_bitfield_units( + pub(crate) fn compute_bitfield_units( &mut self, ctx: &BindgenContext, 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. - pub fn deanonymize_fields(&mut self, ctx: &BindgenContext) { + pub(crate) fn deanonymize_fields(&mut self, ctx: &BindgenContext) { self.fields.deanonymize_fields(ctx, &self.methods); } /// 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` + /// 1. Current `RustTarget` allows for `untagged_union` + /// 2. Each field can derive `Copy` or we use `ManuallyDrop`. /// 3. It's not zero-sized. - pub fn can_be_rust_union( + /// + /// Second boolean returns whether all fields can be copied (and thus + /// `ManuallyDrop` is not needed). + pub(crate) fn is_rust_union( &self, ctx: &BindgenContext, layout: Option<&Layout>, - ) -> bool { - if !ctx.options().rust_features().untagged_union { - return false; + name: &str, + ) -> (bool, bool) { + if !self.is_union() { + return (false, false); + } + + if !ctx.options().untagged_union { + return (false, false); } if self.is_forward_declaration() { - return false; + return (false, false); } + let union_style = if ctx.options().bindgen_wrapper_union.matches(name) { + NonCopyUnionStyle::BindgenWrapper + } else if ctx.options().manually_drop_union.matches(name) { + NonCopyUnionStyle::ManuallyDrop + } else { + ctx.options().default_non_copy_union_style + }; + let all_can_copy = self.fields().iter().all(|f| match *f { Field::DataMember(ref field_data) => { field_data.ty().can_derive_copy(ctx) @@ -1684,15 +1714,15 @@ impl CompInfo { Field::Bitfields(_) => true, }); - if !all_can_copy { - return false; + if !all_can_copy && union_style == NonCopyUnionStyle::BindgenWrapper { + return (false, false); } - if layout.map_or(false, |l| l.size == 0) { - return false; + if layout.is_some_and(|l| l.size == 0) { + return (false, false); } - true + (true, all_can_copy) } } @@ -1752,8 +1782,14 @@ impl DotAttributes for CompInfo { impl IsOpaque for CompInfo { type Extra = Option; - fn is_opaque(&self, ctx: &BindgenContext, layout: &Option) -> bool { - if self.has_non_type_template_params { + fn is_opaque( + &self, + ctx: &BindgenContext, + _layout: &Option, + ) -> bool { + if self.has_non_type_template_params || + self.has_unevaluable_bit_field_width + { return true; } @@ -1781,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/src/ir/context.rs b/bindgen/ir/context.rs similarity index 76% rename from src/ir/context.rs rename to bindgen/ir/context.rs index 9afd16d6a6..346d2932f7 100644 --- a/src/ir/context.rs +++ b/bindgen/ir/context.rs @@ -19,28 +19,28 @@ use super::module::{Module, ModuleKind}; use super::template::{TemplateInstantiation, TemplateParameters}; use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, Type, TypeKind}; -use crate::callbacks::ParseCallbacks; -use crate::clang::{self, Cursor}; -use crate::parse::ClangItemParser; +use crate::clang::{self, ABIKind, Cursor}; +use crate::codegen::CodegenError; use crate::BindgenOptions; use crate::{Entry, HashMap, HashSet}; -use cexpr; -use clang_sys; -use proc_macro2::{Ident, Span}; + +use proc_macro2::{Ident, Span, TokenStream}; +use quote::ToTokens; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap as StdHashMap}; -use std::iter::IntoIterator; use std::mem; +use std::path::Path; /// An identifier for some kind of IR item. #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)] -pub struct ItemId(usize); +pub(crate) struct ItemId(usize); +/// Declare a newtype around `ItemId` with conversion methods. macro_rules! item_id_newtype { ( $( #[$attr:meta] )* - pub struct $name:ident(ItemId) + pub(crate) struct $name:ident(ItemId) where $( #[$checked_attr:meta] )* checked = $checked:ident with $check_method:ident, @@ -51,11 +51,12 @@ macro_rules! item_id_newtype { ) => { $( #[$attr] )* #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)] - pub struct $name(ItemId); + pub(crate) struct $name(ItemId); impl $name { - /// Create an `ItemResolver` from this id. - pub fn into_resolver(self) -> ItemResolver { + /// Create an `ItemResolver` from this ID. + #[allow(dead_code)] + pub(crate) fn into_resolver(self) -> ItemResolver { let id: ItemId = self.into(); id.into() } @@ -83,9 +84,10 @@ macro_rules! item_id_newtype { } } + #[allow(dead_code)] impl ItemId { $( #[$checked_attr] )* - pub fn $checked(&self, ctx: &BindgenContext) -> Option<$name> { + pub(crate) fn $checked(&self, ctx: &BindgenContext) -> Option<$name> { if ctx.resolve_item(*self).kind().$check_method() { Some($name(*self)) } else { @@ -94,7 +96,7 @@ macro_rules! item_id_newtype { } $( #[$expected_attr] )* - pub fn $expected(&self, ctx: &BindgenContext) -> $name { + pub(crate) fn $expected(&self, ctx: &BindgenContext) -> $name { self.$checked(ctx) .expect(concat!( stringify!($expected), @@ -103,7 +105,7 @@ macro_rules! item_id_newtype { } $( #[$unchecked_attr] )* - pub fn $unchecked(&self) -> $name { + pub(crate) fn $unchecked(&self) -> $name { $name(*self) } } @@ -113,7 +115,7 @@ macro_rules! item_id_newtype { item_id_newtype! { /// An identifier for an `Item` whose `ItemKind` is known to be /// `ItemKind::Type`. - pub struct TypeId(ItemId) + pub(crate) struct TypeId(ItemId) where /// Convert this `ItemId` into a `TypeId` if its associated item is a type, /// otherwise return `None`. @@ -125,14 +127,14 @@ item_id_newtype! { expected = expect_type_id, /// Convert this `ItemId` into a `TypeId` without actually checking whether - /// this id actually points to a `Type`. + /// this ID actually points to a `Type`. unchecked = as_type_id_unchecked; } item_id_newtype! { /// An identifier for an `Item` whose `ItemKind` is known to be /// `ItemKind::Module`. - pub struct ModuleId(ItemId) + pub(crate) struct ModuleId(ItemId) where /// Convert this `ItemId` into a `ModuleId` if its associated item is a /// module, otherwise return `None`. @@ -144,14 +146,14 @@ item_id_newtype! { expected = expect_module_id, /// Convert this `ItemId` into a `ModuleId` without actually checking - /// whether this id actually points to a `Module`. + /// whether this ID actually points to a `Module`. unchecked = as_module_id_unchecked; } item_id_newtype! { /// An identifier for an `Item` whose `ItemKind` is known to be /// `ItemKind::Var`. - pub struct VarId(ItemId) + pub(crate) struct VarId(ItemId) where /// Convert this `ItemId` into a `VarId` if its associated item is a var, /// otherwise return `None`. @@ -163,14 +165,14 @@ item_id_newtype! { expected = expect_var_id, /// Convert this `ItemId` into a `VarId` without actually checking whether - /// this id actually points to a `Var`. + /// this ID actually points to a `Var`. unchecked = as_var_id_unchecked; } item_id_newtype! { /// An identifier for an `Item` whose `ItemKind` is known to be /// `ItemKind::Function`. - pub struct FunctionId(ItemId) + pub(crate) struct FunctionId(ItemId) where /// Convert this `ItemId` into a `FunctionId` if its associated item is a function, /// otherwise return `None`. @@ -182,7 +184,7 @@ item_id_newtype! { expected = expect_function_id, /// Convert this `ItemId` into a `FunctionId` without actually checking whether - /// this id actually points to a `Function`. + /// this ID actually points to a `Function`. unchecked = as_function_id_unchecked; } @@ -193,9 +195,9 @@ impl From for usize { } impl ItemId { - /// Get a numeric representation of this id. - pub fn as_usize(&self) -> usize { - (*self).into() + /// Get a numeric representation of this ID. + pub(crate) fn as_usize(self) -> usize { + self.into() } } @@ -305,17 +307,17 @@ enum TypeKey { /// A context used during parsing and generation of structs. #[derive(Debug)] -pub struct BindgenContext { - /// The map of all the items parsed so far, keyed off ItemId. +pub(crate) struct BindgenContext { + /// 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 /// item ids during parsing. types: HashMap, - /// Maps from a cursor to the item id of the named template type parameter + /// 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, @@ -326,13 +328,13 @@ pub 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: @@ -342,7 +344,7 @@ pub 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, @@ -351,11 +353,19 @@ pub 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. + /// + /// This is needed so that items are created in the order they are defined in. + /// + /// The key is the included file, the value is a pair of the source file and + /// the position of the `#include` directive in the source file. + includes: StdHashMap, + /// A set of all the included filenames. - deps: BTreeSet, + deps: BTreeSet>, /// The active replacements collected from replaces="xxx" annotations. replacements: HashMap, ItemId>, @@ -367,15 +377,24 @@ pub struct BindgenContext { /// The translation unit for parsing. translation_unit: clang::TranslationUnit, + /// The translation unit for macro fallback parsing. + fallback_tu: Option, + /// Target information that can be useful for some stuff. - target_info: Option, + target_info: clang::TargetInfo, /// 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, + /// Whether a bindgen float16 was generated + generated_bindgen_float16: Cell, + /// The set of `ItemId`s that are allowlisted. This the very first thing /// computed after parsing our IR, and before running any of our analyses. allowlisted: Option, @@ -390,7 +409,7 @@ pub struct BindgenContext { /// It's computed right after computing the allowlisted items. codegen_items: Option, - /// Map from an item's id to the set of template parameter items that it + /// Map from an item's ID to the set of template parameter items that it /// uses. See `ir::named` for more details. Always `Some` during the codegen /// phase. used_template_parameters: Option>, @@ -399,6 +418,22 @@ pub struct BindgenContext { /// bitfield allocation units computed. Drained in `compute_bitfield_units`. need_bitfield_allocation: Vec, + /// The set of enums that are defined by a pair of `enum` and `typedef`, + /// which is legal in C (but not C++). + /// + /// ```c++ + /// // in either order + /// enum Enum { Variants... }; + /// typedef int16_t Enum; + /// ``` + /// + /// The stored `ItemId` is that of the `TypeKind::Enum`, not of the + /// `TypeKind::Alias`. + /// + /// This is populated when we enter codegen by `compute_enum_typedef_combos` + /// and is always `None` before that and `Some` after. + enum_typedef_combos: Option>, + /// The set of (`ItemId`s of) types that can't derive debug. /// /// This is populated when we enter codegen by `compute_cannot_derive_debug` @@ -464,15 +499,10 @@ pub struct BindgenContext { /// A traversal of allowlisted items. struct AllowlistedItemsTraversal<'ctx> { ctx: &'ctx BindgenContext, - traversal: ItemTraversal< - 'ctx, - ItemSet, - Vec, - for<'a> fn(&'a BindgenContext, Edge) -> bool, - >, + traversal: ItemTraversal<'ctx, ItemSet, Vec>, } -impl<'ctx> Iterator for AllowlistedItemsTraversal<'ctx> { +impl Iterator for AllowlistedItemsTraversal<'_> { type Item = ItemId; fn next(&mut self) -> Option { @@ -490,7 +520,7 @@ impl<'ctx> Iterator for AllowlistedItemsTraversal<'ctx> { impl<'ctx> AllowlistedItemsTraversal<'ctx> { /// Construct a new allowlisted items traversal. - pub fn new( + pub(crate) fn new( ctx: &'ctx BindgenContext, roots: R, predicate: for<'a> fn(&'a BindgenContext, Edge) -> bool, @@ -507,7 +537,10 @@ impl<'ctx> AllowlistedItemsTraversal<'ctx> { impl BindgenContext { /// Construct the context for the given `options`. - pub(crate) fn new(options: BindgenOptions) -> Self { + pub(crate) fn new( + options: BindgenOptions, + input_unsaved_files: &[clang::UnsavedFile], + ) -> Self { // TODO(emilio): Use the CXTargetInfo here when available. // // see: https://reviews.llvm.org/D32389 @@ -524,7 +557,7 @@ impl BindgenContext { &index, "", &options.clang_args, - &options.input_unsaved_files, + input_unsaved_files, parse_options, ).expect("libclang error; possible causes include: - Invalid flag syntax @@ -540,14 +573,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" let root_module_id = root_module.id().as_module_id_unchecked(); // depfiles need to include the explicitly listed headers too - let mut deps = BTreeSet::default(); - if let Some(filename) = &options.input_header { - deps.insert(filename.clone()); - } - deps.extend(options.extra_input_headers.iter().cloned()); + let deps = options.input_headers.iter().cloned().collect(); BindgenContext { items: vec![Some(root_module)], + includes: Default::default(), deps, types: Default::default(), type_params: Default::default(), @@ -561,14 +591,18 @@ If you encounter an error missing from this list, please file an issue or a PR!" collected_typerefs: false, in_codegen: false, translation_unit, + fallback_tu: None, target_info, 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, used_template_parameters: None, need_bitfield_allocation: Default::default(), + enum_typedef_combos: None, cannot_derive_debug: None, cannot_derive_default: None, cannot_derive_copy: None, @@ -583,65 +617,76 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Returns `true` if the target architecture is wasm32 - pub fn is_target_wasm32(&self) -> bool { - match self.target_info { - Some(ref ti) => ti.triple.starts_with("wasm32-"), - None => false, - } + pub(crate) fn is_target_wasm32(&self) -> bool { + 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 fn timer<'a>(&self, name: &'a str) -> Timer<'a> { + pub(crate) fn timer<'a>(&self, name: &'a str) -> Timer<'a> { Timer::new(name).with_output(self.options.time_phases) } /// Returns the pointer width to use for the target for the current /// translation. - pub fn target_pointer_size(&self) -> usize { - if let Some(ref ti) = self.target_info { - return ti.pointer_width / 8; - } - mem::size_of::<*mut ()>() + pub(crate) fn target_pointer_size(&self) -> usize { + self.target_info.pointer_width / 8 + } + + /// Returns the ABI, which is mostly useful for determining the mangling kind. + pub(crate) fn abi_kind(&self) -> ABIKind { + self.target_info.abi } /// Get the stack of partially parsed types that we are in the middle of /// parsing. - pub fn currently_parsed_types(&self) -> &[PartialType] { + pub(crate) fn currently_parsed_types(&self) -> &[PartialType] { &self.currently_parsed_types[..] } /// Begin parsing the given partial type, and push it onto the /// `currently_parsed_types` stack so that we won't infinite recurse if we /// run into a reference to it while parsing it. - pub fn begin_parsing(&mut self, partial_ty: PartialType) { + pub(crate) fn begin_parsing(&mut self, partial_ty: PartialType) { self.currently_parsed_types.push(partial_ty); } /// Finish parsing the current partial type, pop it off the /// `currently_parsed_types` stack, and return it. - pub fn finish_parsing(&mut self) -> PartialType { + pub(crate) fn finish_parsing(&mut self) -> PartialType { self.currently_parsed_types.pop().expect( "should have been parsing a type, if we finished parsing a type", ) } - /// Get the user-provided callbacks by reference, if any. - pub fn parse_callbacks(&self) -> Option<&dyn ParseCallbacks> { - self.options().parse_callbacks.as_deref() + /// Add the location of the `#include` directive for the `included_file`. + pub(crate) fn add_include( + &mut self, + source_file: String, + included_file: String, + offset: usize, + ) { + self.includes + .entry(included_file) + .or_insert((source_file, offset)); } - /// Add another path to the set of included files. - pub fn include_file(&mut self, filename: String) { - if let Some(cbs) = self.parse_callbacks() { - cbs.include_file(&filename); - } - self.deps.insert(filename); + /// Get the location of the first `#include` directive for the `included_file`. + pub(crate) fn included_file_location( + &self, + included_file: &str, + ) -> Option<(String, usize)> { + self.includes.get(included_file).cloned() + } + + /// Add an included file. + pub(crate) fn add_dep(&mut self, dep: Box) { + self.deps.insert(dep); } /// Get any included files. - pub fn deps(&self) -> &BTreeSet { + pub(crate) fn deps(&self) -> &BTreeSet> { &self.deps } @@ -649,16 +694,13 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// /// This inserts it into the internal items set, and its type into the /// internal types set. - pub fn add_item( + pub(crate) fn add_item( &mut self, item: Item, 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() || @@ -682,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" @@ -710,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() @@ -725,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) }; @@ -742,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] { @@ -764,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() @@ -774,11 +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 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(), @@ -792,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" @@ -809,28 +844,28 @@ 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 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. /// Mangles a name so it doesn't conflict with any keyword. #[rustfmt::skip] - pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> { + pub(crate) fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> { if name.contains('@') || name.contains('?') || name.contains('$') || matches!( name, - "abstract" | "alignof" | "as" | "async" | "become" | + "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" | @@ -842,9 +877,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) { let mut s = name.to_owned(); - s = s.replace("@", "_"); - s = s.replace("?", "_"); - s = s.replace("$", "_"); + s = s.replace('@', "_"); + s = s.replace('?', "_"); + s = s.replace('$', "_"); s.push('_'); return Cow::Owned(s); } @@ -852,7 +887,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Returns a mangled name as a rust identifier. - pub fn rust_ident(&self, name: S) -> Ident + pub(crate) fn rust_ident(&self, name: S) -> Ident where S: AsRef, { @@ -860,7 +895,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Returns a mangled name as a rust identifier. - pub fn rust_ident_raw(&self, name: T) -> Ident + pub(crate) fn rust_ident_raw(&self, name: T) -> Ident where T: AsRef, { @@ -868,7 +903,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Iterate over all items that have been defined. - pub fn items(&self) -> impl Iterator { + pub(crate) fn items(&self) -> impl Iterator { self.items.iter().enumerate().filter_map(|(index, item)| { let item = item.as_ref()?; Some((ItemId(index), item)) @@ -876,30 +911,27 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Have we collected all unresolved type references yet? - pub fn collected_typerefs(&self) -> bool { + pub(crate) fn collected_typerefs(&self) -> bool { self.collected_typerefs } /// 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 } @@ -955,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 @@ -1030,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() { @@ -1061,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(); @@ -1073,7 +1104,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Relocate the replacement item from where it was declared, to // where the thing it is replacing was declared. // - // First, we'll make sure that its parent id is correct. + // First, we'll make sure that its parent ID is correct. let old_parent = self.resolve_item(replacement_id).parent_id(); if new_parent == old_parent { @@ -1098,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()) }) }) @@ -1140,9 +1171,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Enter the code generation phase, invoke the given callback `cb`, and /// leave the code generation phase. - pub(crate) fn gen(mut self, cb: F) -> (Out, BindgenOptions) + pub(crate) fn gen( + mut self, + cb: F, + ) -> Result<(Out, BindgenOptions), CodegenError> where - F: FnOnce(&Self) -> Out, + F: FnOnce(&Self) -> Result, { self.in_codegen = true; @@ -1168,6 +1202,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.compute_sizedness(); self.compute_has_destructor(); self.find_used_template_parameters(); + self.compute_enum_typedef_combos(); self.compute_cannot_derive_debug(); self.compute_cannot_derive_default(); self.compute_cannot_derive_copy(); @@ -1176,15 +1211,15 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.compute_cannot_derive_hash(); self.compute_cannot_derive_partialord_partialeq_or_eq(); - let ret = cb(&self); - (ret, self.options) + let ret = cb(&self)?; + Ok((ret, self.options)) } - /// When the `testing_only_extra_assertions` feature is enabled, this + /// 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") { + if cfg!(feature = "__testing_only_extra_assertions") { for _ in self.assert_no_dangling_item_traversal() { // The iterator's next method does the asserting for us. } @@ -1193,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( @@ -1205,13 +1240,13 @@ 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, walk over + /// When the `__testing_only_extra_assertions` feature is enabled, walk over /// every item and ensure that it is in the children set of one of its /// module ancestors. fn assert_every_item_in_a_module(&self) { - if cfg!(feature = "testing_only_extra_assertions") { + 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 { @@ -1229,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" ); } } @@ -1255,8 +1284,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.sizedness = Some(analyze::(self)); } - /// Look up whether the type with the given id is sized or not. - pub fn lookup_sizedness(&self, id: TypeId) -> SizednessResult { + /// Look up whether the type with the given ID is sized or not. + pub(crate) fn lookup_sizedness(&self, id: TypeId) -> SizednessResult { assert!( self.in_codegen_phase(), "We only compute sizedness after we've entered codegen" @@ -1266,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) } @@ -1278,7 +1307,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Look up whether the item with `id` has vtable or not. - pub fn lookup_has_vtable(&self, id: TypeId) -> HasVtableResult { + pub(crate) fn lookup_has_vtable(&self, id: TypeId) -> HasVtableResult { assert!( self.in_codegen_phase(), "We only compute vtables when we enter codegen" @@ -1290,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) } @@ -1302,7 +1331,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Look up whether the item with `id` has a destructor. - pub fn lookup_has_destructor(&self, id: TypeId) -> bool { + pub(crate) fn lookup_has_destructor(&self, id: TypeId) -> bool { assert!( self.in_codegen_phase(), "We only compute destructors when we enter codegen" @@ -1346,7 +1375,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// manually provide a definition for them. To give them the most /// flexibility when doing that, we assume that they use every template /// parameter and always pass template arguments through in instantiations. - pub fn uses_template_parameter( + pub(crate) fn uses_template_parameter( &self, item: ItemId, template_param: TypeId, @@ -1370,15 +1399,14 @@ 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, /// `false` otherwise. /// /// Has the same restrictions that `uses_template_parameter` has. - pub fn uses_any_template_parameters(&self, item: ItemId) -> bool { + pub(crate) fn uses_any_template_parameters(&self, item: ItemId) -> bool { assert!( self.in_codegen_phase(), "We only compute template parameter usage as we enter codegen" @@ -1390,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 @@ -1402,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?"); } @@ -1416,38 +1444,38 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Get the root module. - pub fn root_module(&self) -> ModuleId { + pub(crate) fn root_module(&self) -> ModuleId { self.root_module } - /// Resolve a type with the given id. + /// Resolve a type with the given ID. /// /// Panics if there is no item for the given `TypeId` or if the resolved /// item is not a `Type`. - pub fn resolve_type(&self, type_id: TypeId) -> &Type { + pub(crate) fn resolve_type(&self, type_id: TypeId) -> &Type { self.resolve_item(type_id).kind().expect_type() } - /// Resolve a function with the given id. + /// Resolve a function with the given ID. /// /// Panics if there is no item for the given `FunctionId` or if the resolved /// item is not a `Function`. - pub fn resolve_func(&self, func_id: FunctionId) -> &Function { + pub(crate) fn resolve_func(&self, func_id: FunctionId) -> &Function { self.resolve_item(func_id).kind().expect_function() } /// Resolve the given `ItemId` as a type, or `None` if there is no item with - /// the given id. + /// the given ID. /// - /// Panics if the id resolves to an item that is not a type. - pub fn safe_resolve_type(&self, type_id: TypeId) -> Option<&Type> { + /// Panics if the ID resolves to an item that is not a type. + pub(crate) fn safe_resolve_type(&self, type_id: TypeId) -> Option<&Type> { self.resolve_item_fallible(type_id) .map(|t| t.kind().expect_type()) } /// Resolve the given `ItemId` into an `Item`, or `None` if no such item /// exists. - pub fn resolve_item_fallible>( + pub(crate) fn resolve_item_fallible>( &self, id: Id, ) -> Option<&Item> { @@ -1456,17 +1484,17 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Resolve the given `ItemId` into an `Item`. /// - /// Panics if the given id does not resolve to any item. - pub fn resolve_item>(&self, item_id: Id) -> &Item { + /// Panics if the given ID does not resolve to any item. + pub(crate) fn resolve_item>(&self, item_id: Id) -> &Item { 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:?}"), } } /// Get the current module. - pub fn current_module(&self) -> ModuleId { + pub(crate) fn current_module(&self) -> ModuleId { self.current_module } @@ -1476,22 +1504,22 @@ 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 fn add_semantic_parent( + pub(crate) fn add_semantic_parent( &mut self, - definition: clang::Cursor, + definition: Cursor, parent_id: ItemId, ) { self.semantic_parents.insert(definition, parent_id); } /// Returns a known semantic parent for a given definition. - pub fn known_semantic_parent( + 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, @@ -1539,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 = @@ -1564,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 @@ -1595,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); @@ -1641,7 +1668,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" clang_sys::CXCursor_TypeRef | clang_sys::CXCursor_TypedefDecl | clang_sys::CXCursor_TypeAliasDecl => { - // The `with_id` id will potentially end up unused if we give up + // The `with_id` ID will potentially end up unused if we give up // on this type (for example, because it has const value // template args), so if we pass `with_id` as the parent, it is // potentially a dangling reference. Instead, use the canonical @@ -1728,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()); @@ -1739,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; } @@ -1791,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); @@ -1800,7 +1825,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// If we have already resolved the type for the given type declaration, /// return its `ItemId`. Otherwise, return `None`. - pub fn get_resolved_type( + pub(crate) fn get_resolved_type( &self, decl: &clang::CanonicalTypeDeclaration, ) -> Option { @@ -1811,29 +1836,25 @@ 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 /// because we already have it in the map. - pub fn builtin_or_resolved_ty( + pub(crate) fn builtin_or_resolved_ty( &mut self, 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: // @@ -1886,7 +1907,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// We should probably make the constness tracking separate, so it doesn't /// bloat that much, but hey, we already bloat the heck out of builtin /// types. - pub fn build_ty_wrapper( + pub(crate) fn build_ty_wrapper( &mut self, with_id: ItemId, wrapped_id: TypeId, @@ -1899,7 +1920,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// A wrapper over a type that adds a const qualifier explicitly. /// /// Needed to handle const methods in C++, wrapping the type . - pub fn build_const_wrapper( + pub(crate) fn build_const_wrapper( &mut self, with_id: ItemId, wrapped_id: TypeId, @@ -1936,8 +1957,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" with_id.as_type_id_unchecked() } - /// Returns the next item id to be used for an item. - pub fn next_item_id(&mut self) -> ItemId { + /// Returns the next item ID to be used for an item. + pub(crate) fn next_item_id(&mut self) -> ItemId { let ret = ItemId(self.items.len()); self.items.push(None); ret @@ -1958,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), @@ -1966,6 +1990,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" CXType_ULongLong => TypeKind::Int(IntKind::ULongLong), CXType_Int128 => TypeKind::Int(IntKind::I128), CXType_UInt128 => TypeKind::Int(IntKind::U128), + CXType_Float16 | CXType_Half => TypeKind::Float(FloatKind::Float16), CXType_Float => TypeKind::Float(FloatKind::Float), CXType_Double => TypeKind::Float(FloatKind::Double), CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble), @@ -1974,13 +1999,13 @@ If you encounter an error missing from this list, please file an issue or a PR!" let float_type = ty.elem_type().expect("Not able to resolve complex type?"); let float_kind = match float_type.kind() { + CXType_Float16 | CXType_Half => FloatKind::Float16, CXType_Float => FloatKind::Float, CXType_Double => FloatKind::Double, 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) @@ -2007,17 +2032,104 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Get the current Clang translation unit that is being processed. - pub fn translation_unit(&self) -> &clang::TranslationUnit { + pub(crate) fn translation_unit(&self) -> &clang::TranslationUnit { &self.translation_unit } + /// Initialize fallback translation unit if it does not exist and + /// then return a mutable reference to the fallback translation unit. + pub(crate) fn try_ensure_fallback_translation_unit( + &mut self, + ) -> Option<&mut clang::FallbackTranslationUnit> { + if self.fallback_tu.is_none() { + let file = format!( + "{}/.macro_eval.c", + match self.options().clang_macro_fallback_build_dir { + Some(ref path) => path.as_os_str().to_str()?, + None => ".", + } + ); + + let index = clang::Index::new(false, false); + + let mut header_names_to_compile = Vec::new(); + let mut header_paths = Vec::new(); + 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("") { + header_paths.push("."); + } else { + header_paths.push(header_path.as_os_str().to_str()?); + } + } else { + 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()); + } + 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.pch" + ); + + 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()); + } + 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, + &single_header, + &c_args, + &[], + clang_sys::CXTranslationUnit_ForSerialization, + )?; + tu.save(&pch).ok()?; + + let mut c_args = vec![ + "-include-pch".to_string().into_boxed_str(), + pch.clone().into_boxed_str(), + ]; + 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() + } + /// Have we parsed the macro named `macro_name` already? - pub fn parsed_macro(&self, macro_name: &[u8]) -> bool { + pub(crate) fn parsed_macro(&self, macro_name: &[u8]) -> bool { self.parsed_macros.contains_key(macro_name) } /// Get the currently parsed macros. - pub fn parsed_macros( + pub(crate) fn parsed_macros( &self, ) -> &StdHashMap, cexpr::expr::EvalResult> { debug_assert!(!self.in_codegen_phase()); @@ -2025,7 +2137,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Mark the macro named `macro_name` as parsed. - pub fn note_parsed_macro( + pub(crate) fn note_parsed_macro( &mut self, id: Vec, value: cexpr::expr::EvalResult, @@ -2034,31 +2146,26 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Are we in the codegen phase? - pub fn in_codegen_phase(&self) -> bool { + pub(crate) fn in_codegen_phase(&self) -> bool { self.in_codegen } - /// Mark the type with the given `name` as replaced by the type with id + /// Mark the type with the given `name` as replaced by the type with ID /// `potential_ty`. /// /// Replacement types are declared using the `replaces="xxx"` annotation, /// and implies that the original type is hidden. - pub fn replace(&mut self, name: &[String], potential_ty: ItemId) { + 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 ); } } @@ -2066,7 +2173,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Has the item with the given `name` and `id` been replaced by another /// type? - pub fn is_replaced_type>( + pub(crate) fn is_replaced_type>( &self, path: &[String], id: Id, @@ -2076,12 +2183,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Is the type with the given `name` marked as opaque? - pub fn opaque_by_name(&self, path: &[String]) -> bool { + pub(crate) fn opaque_by_name(&self, path: &[String]) -> bool { debug_assert!( self.in_codegen_phase(), "You're not supposed to call this yet" ); - self.options.opaque_types.matches(&path[1..].join("::")) + self.options.opaque_types.matches(path[1..].join("::")) } /// Get the options used to configure this bindgen context. @@ -2093,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(), @@ -2104,17 +2211,22 @@ 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; - let mut found_namespace_keyword = false; + let mut looking_for_name = false; for token in cursor.tokens().iter() { match token.spelling() { b"inline" => { - assert!(!found_namespace_keyword); - assert!(kind != ModuleKind::Inline); + debug_assert!( + kind != ModuleKind::Inline, + "Multiple inline keywords?" + ); kind = ModuleKind::Inline; + // When hitting a nested inline namespace we get a spelling + // that looks like ["inline", "foo"]. Deal with it properly. + looking_for_name = true; } // The double colon allows us to handle nested namespaces like // namespace foo::bar { } @@ -2123,55 +2235,47 @@ If you encounter an error missing from this list, please file an issue or a PR!" // but the tokenization of the second begins with the double // colon. That's ok, so we only need to handle the weird // tokenization here. - // - // Fortunately enough, inline nested namespace specifiers aren't - // a thing, and are invalid C++ :) b"namespace" | b"::" => { - found_namespace_keyword = true; + looking_for_name = true; } b"{" => { - assert!(found_namespace_keyword); + // This should be an anonymous namespace. + assert!(looking_for_name); break; } - name if found_namespace_keyword => { - if module_name.is_none() { - module_name = - Some(String::from_utf8_lossy(name).into_owned()); + name => { + if looking_for_name { + if module_name.is_none() { + module_name = Some( + String::from_utf8_lossy(name).into_owned(), + ); + } + break; } - break; - } - spelling if !found_namespace_keyword => { - // 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. + // 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(spelling), - token, - cursor - ); - } - spelling => { - panic!( - "Unknown token '{}' while processing namespace at {:?} in {:?}", - String::from_utf8_lossy(spelling), - token, - cursor - ); + 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 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(); @@ -2202,7 +2306,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Start traversing the module with the given `module_id`, invoke the /// callback `cb`, and then return to traversing the original module. - pub fn with_module(&mut self, module_id: ModuleId, cb: F) + pub(crate) fn with_module(&mut self, module_id: ModuleId, cb: F) where F: FnOnce(&mut Self), { @@ -2220,22 +2324,22 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// /// If no items are explicitly allowlisted, then all items are considered /// allowlisted. - pub fn allowlisted_items(&self) -> &ItemSet { + 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() } /// Check whether a particular blocklisted type implements a trait or not. /// Results may be cached. - pub fn blocklisted_type_implements_trait( + pub(crate) fn blocklisted_type_implements_trait( &self, item: &Item, 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 @@ -2246,43 +2350,51 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_insert_with(|| { item.expect_type() .name() - .and_then(|name| match self.options.parse_callbacks { - Some(ref cb) => cb.blocklisted_type_implements_trait( - name, - derive_trait, - ), - // Sized integer types from get mapped to Rust primitive - // types regardless of whether they are blocklisted, so ensure that - // standard traits are considered derivable for them too. - None => match name { - "int8_t" | "uint8_t" | "int16_t" | "uint16_t" | - "int32_t" | "uint32_t" | "int64_t" | - "uint64_t" | "uintptr_t" | "intptr_t" | - "ptrdiff_t" => Some(CanDerive::Yes), - "size_t" if self.options.size_t_is_usize => { - Some(CanDerive::Yes) - } - "ssize_t" if self.options.size_t_is_usize => { + .and_then(|name| { + if self.options.parse_callbacks.is_empty() { + // Sized integer types from get mapped to Rust primitive + // types regardless of whether they are blocklisted, so ensure that + // standard traits are considered derivable for them too. + if self.is_stdint_type(name) { Some(CanDerive::Yes) + } else { + Some(CanDerive::No) } - _ => Some(CanDerive::No), - }, + } else { + self.options.last_callback(|cb| { + cb.blocklisted_type_implements_trait( + name, + derive_trait, + ) + }) + } }) .unwrap_or(CanDerive::No) }) } + /// Is the given type a type from that corresponds to a Rust primitive type? + pub(crate) fn is_stdint_type(&self, name: &str) -> bool { + match name { + "int8_t" | "uint8_t" | "int16_t" | "uint16_t" | "int32_t" | + "uint32_t" | "int64_t" | "uint64_t" | "uintptr_t" | + "intptr_t" | "ptrdiff_t" => true, + "size_t" | "ssize_t" => self.options.size_t_is_usize, + _ => false, + } + } + /// Get a reference to the set of items we should generate. - pub fn codegen_items(&self) -> &ItemSet { + 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"); @@ -2297,7 +2409,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" if self.options().allowlisted_types.is_empty() && self.options().allowlisted_functions.is_empty() && self.options().allowlisted_vars.is_empty() && - self.options().allowlisted_files.is_empty() + self.options().allowlisted_files.is_empty() && + self.options().allowlisted_items.is_empty() { return true; } @@ -2317,7 +2430,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" if self .options() .allowlisted_files - .matches(&filename) + .matches(filename) { return true; } @@ -2326,7 +2439,12 @@ 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; + } + match *item.kind() { ItemKind::Module(..) => true, ItemKind::Function(_) => { @@ -2359,7 +2477,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" TypeKind::Opaque | TypeKind::TypeParam => return true, _ => {} - }; + } + if self.is_stdint_type(&name) { + return true; + } } // Unnamed top-level enums are special and we @@ -2372,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() { @@ -2390,6 +2510,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" let name = prefix_path[1..].join("::"); prefix_path.pop().unwrap(); self.options().allowlisted_vars.matches(&name) + || self + .options() + .allowlisted_items + .matches(name) }) } } @@ -2437,21 +2561,25 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.codegen_items = Some(codegen_items); for item in self.options().allowlisted_functions.unmatched_items() { - warn!("unused option: --allowlist-function {}", item); + unused_regex_diagnostic(item, "--allowlist-function", self); } for item in self.options().allowlisted_vars.unmatched_items() { - warn!("unused option: --allowlist-var {}", item); + unused_regex_diagnostic(item, "--allowlist-var", self); } for item in self.options().allowlisted_types.unmatched_items() { - warn!("unused option: --allowlist-type {}", item); + unused_regex_diagnostic(item, "--allowlist-type", self); + } + + for item in self.options().allowlisted_items.unmatched_items() { + unused_regex_diagnostic(item, "--allowlist-items", self); } } /// Convenient method for getting the prefix to use for most traits in /// codegen depending on the `use_core` option. - pub fn trait_prefix(&self) -> Ident { + pub(crate) fn trait_prefix(&self) -> Ident { if self.options().use_core { self.rust_ident_raw("core") } else { @@ -2459,16 +2587,107 @@ 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 fn generated_bindgen_complex(&self) { - self.generated_bindgen_complex.set(true) + pub(crate) fn generated_bindgen_complex(&self) { + self.generated_bindgen_complex.set(true); } /// Whether we need to generate the bindgen complex type - pub fn need_bindgen_complex_type(&self) -> bool { + pub(crate) fn need_bindgen_complex_type(&self) -> bool { self.generated_bindgen_complex.get() } + /// Call if a bindgen float16 is generated + pub(crate) fn generated_bindgen_float16(&self) { + self.generated_bindgen_float16.set(true); + } + + /// Whether we need to generate the bindgen float16 type + pub(crate) fn need_bindgen_float16_type(&self) -> bool { + self.generated_bindgen_float16.get() + } + + /// Compute which `enum`s have an associated `typedef` definition. + fn compute_enum_typedef_combos(&mut self) { + let _t = self.timer("compute_enum_typedef_combos"); + assert!(self.enum_typedef_combos.is_none()); + + let mut enum_typedef_combos = HashSet::default(); + for item in &self.items { + if let Some(ItemKind::Module(module)) = + item.as_ref().map(Item::kind) + { + // Find typedefs in this module, and build set of their names. + let mut names_of_typedefs = HashSet::default(); + for child_id in module.children() { + if let Some(ItemKind::Type(ty)) = + self.items[child_id.0].as_ref().map(Item::kind) + { + if let (Some(name), TypeKind::Alias(type_id)) = + (ty.name(), ty.kind()) + { + // We disregard aliases that refer to the enum + // itself, such as in `typedef enum { ... } Enum;`. + if type_id + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(self) + .expect_type() + .is_int() + { + names_of_typedefs.insert(name); + } + } + } + } + + // Find enums in this module, and record the ID of each one that + // has a typedef. + for child_id in module.children() { + if let Some(ItemKind::Type(ty)) = + self.items[child_id.0].as_ref().map(Item::kind) + { + if let (Some(name), true) = (ty.name(), ty.is_enum()) { + if names_of_typedefs.contains(name) { + enum_typedef_combos.insert(*child_id); + } + } + } + } + } + } + + self.enum_typedef_combos = Some(enum_typedef_combos); + } + + /// Look up whether `id` refers to an `enum` whose underlying type is + /// defined by a `typedef`. + pub(crate) fn is_enum_typedef_combo(&self, id: ItemId) -> bool { + assert!( + self.in_codegen_phase(), + "We only compute enum_typedef_combos when we enter codegen", + ); + self.enum_typedef_combos.as_ref().unwrap().contains(&id) + } + /// Compute whether we can derive debug. fn compute_cannot_derive_debug(&mut self) { let _t = self.timer("compute_cannot_derive_debug"); @@ -2484,7 +2703,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Look up whether the item with `id` can /// derive debug or not. - pub fn lookup_can_derive_debug>(&self, id: Id) -> bool { + pub(crate) fn lookup_can_derive_debug>( + &self, + id: Id, + ) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2511,7 +2733,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Look up whether the item with `id` can /// derive default or not. - pub fn lookup_can_derive_default>(&self, id: Id) -> bool { + pub(crate) fn lookup_can_derive_default>( + &self, + id: Id, + ) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2549,7 +2774,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Look up whether the item with `id` can /// derive hash or not. - pub fn lookup_can_derive_hash>(&self, id: Id) -> bool { + pub(crate) fn lookup_can_derive_hash>( + &self, + id: Id, + ) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2561,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()); @@ -2578,7 +2806,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`. - pub fn lookup_can_derive_partialeq_or_partialord>( + pub(crate) fn lookup_can_derive_partialeq_or_partialord< + Id: Into, + >( &self, id: Id, ) -> CanDerive { @@ -2594,12 +2824,15 @@ 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) } /// Look up whether the item with `id` can derive `Copy` or not. - pub fn lookup_can_derive_copy>(&self, id: Id) -> bool { + pub(crate) fn lookup_can_derive_copy>( + &self, + id: Id, + ) -> bool { assert!( self.in_codegen_phase(), "We only compute can_derive_debug when we enter codegen" @@ -2622,7 +2855,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Look up whether the item with `id` has type parameter in array or not. - pub fn lookup_has_type_param_in_array>( + pub(crate) fn lookup_has_type_param_in_array>( &self, id: Id, ) -> bool { @@ -2649,7 +2882,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Look up whether the item with `id` has array or not. - pub fn lookup_has_float>(&self, id: Id) -> bool { + pub(crate) fn lookup_has_float>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute has float when we enter codegen" @@ -2661,53 +2894,71 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Check if `--no-partialeq` flag is enabled for this item. - pub fn no_partialeq_by_name(&self, item: &Item) -> bool { + pub(crate) fn no_partialeq_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().no_partialeq_types.matches(&name) + self.options().no_partialeq_types.matches(name) } /// Check if `--no-copy` flag is enabled for this item. - pub fn no_copy_by_name(&self, item: &Item) -> bool { + pub(crate) fn no_copy_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().no_copy_types.matches(&name) + self.options().no_copy_types.matches(name) } /// Check if `--no-debug` flag is enabled for this item. - pub fn no_debug_by_name(&self, item: &Item) -> bool { + pub(crate) fn no_debug_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().no_debug_types.matches(&name) + self.options().no_debug_types.matches(name) } /// Check if `--no-default` flag is enabled for this item. - pub fn no_default_by_name(&self, item: &Item) -> bool { + pub(crate) fn no_default_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().no_default_types.matches(&name) + self.options().no_default_types.matches(name) } /// Check if `--no-hash` flag is enabled for this item. - pub fn no_hash_by_name(&self, item: &Item) -> bool { + pub(crate) fn no_hash_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().no_hash_types.matches(&name) + self.options().no_hash_types.matches(name) } /// Check if `--must-use-type` flag is enabled for this item. - pub fn must_use_type_by_name(&self, item: &Item) -> bool { + pub(crate) fn must_use_type_by_name(&self, item: &Item) -> bool { let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().must_use_types.matches(&name) + self.options().must_use_types.matches(name) + } + + /// Wrap some tokens in an `unsafe` block if the `--wrap-unsafe-ops` option is enabled. + pub(crate) fn wrap_unsafe_ops(&self, tokens: impl ToTokens) -> TokenStream { + if self.options.wrap_unsafe_ops { + quote!(unsafe { #tokens }) + } else { + tokens.into_token_stream() + } + } + + /// Get the suffix to be added to `static` functions if the `--wrap-static-fns` option is + /// enabled. + pub(crate) fn wrap_static_fns_suffix(&self) -> &str { + self.options() + .wrap_static_fns_suffix + .as_deref() + .unwrap_or(crate::DEFAULT_NON_EXTERN_FNS_SUFFIX) } } /// A builder struct for configuring item resolution options. #[derive(Debug, Copy, Clone)] -pub struct ItemResolver { +pub(crate) struct ItemResolver { id: ItemId, through_type_refs: bool, through_type_aliases: bool, } impl ItemId { - /// Create an `ItemResolver` from this item id. - pub fn into_resolver(self) -> ItemResolver { + /// Create an `ItemResolver` from this item ID. + pub(crate) fn into_resolver(self) -> ItemResolver { self.into() } } @@ -2722,8 +2973,8 @@ where } impl ItemResolver { - /// Construct a new `ItemResolver` from the given id. - pub fn new>(id: Id) -> ItemResolver { + /// Construct a new `ItemResolver` from the given ID. + pub(crate) fn new>(id: Id) -> ItemResolver { let id = id.into(); ItemResolver { id, @@ -2733,19 +2984,19 @@ impl ItemResolver { } /// Keep resolving through `Type::TypeRef` items. - pub fn through_type_refs(mut self) -> ItemResolver { + pub(crate) fn through_type_refs(mut self) -> ItemResolver { self.through_type_refs = true; self } /// Keep resolving through `Type::Alias` items. - pub fn through_type_aliases(mut self) -> ItemResolver { + pub(crate) fn through_type_aliases(mut self) -> ItemResolver { self.through_type_aliases = true; self } /// Finish configuring and perform the actual item resolution. - pub fn resolve(self, ctx: &BindgenContext) -> &Item { + pub(crate) fn resolve(self, ctx: &BindgenContext) -> &Item { assert!(ctx.collected_typerefs()); let mut id = self.id; @@ -2782,7 +3033,7 @@ impl ItemResolver { /// A type that we are in the middle of parsing. #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct PartialType { +pub(crate) struct PartialType { decl: Cursor, // Just an ItemId, and not a TypeId, because we haven't finished this type // yet, so there's still time for things to go wrong. @@ -2791,19 +3042,19 @@ pub struct PartialType { impl PartialType { /// Construct a new `PartialType`. - pub fn new(decl: Cursor, id: ItemId) -> PartialType { + pub(crate) fn new(decl: Cursor, id: ItemId) -> PartialType { // assert!(decl == decl.canonical()); PartialType { decl, id } } /// The cursor pointing to this partial type's declaration location. - pub fn decl(&self) -> &Cursor { + pub(crate) fn decl(&self) -> &Cursor { &self.decl } /// The item ID allocated for this type. This is *NOT* a key for an entry in /// the context's item set yet! - pub fn id(&self) -> ItemId { + pub(crate) fn id(&self) -> ItemId { self.id } } @@ -2831,7 +3082,7 @@ impl TemplateParameters for PartialType { num_params += 1; } _ => {} - }; + } clang_sys::CXChildVisit_Continue }); num_params @@ -2840,3 +3091,23 @@ impl TemplateParameters for PartialType { } } } + +fn unused_regex_diagnostic(item: &str, name: &str, _ctx: &BindgenContext) { + warn!("unused option: {name} {item}"); + + #[cfg(feature = "experimental")] + if _ctx.options().emit_diagnostics { + use crate::diagnostics::{Diagnostic, Level}; + + Diagnostic::default() + .with_title( + format!("Unused regular expression: `{item}`."), + Level::Warning, + ) + .add_annotation( + format!("This regular expression was passed to `{name}`."), + Level::Note, + ) + .display(); + } +} diff --git a/bindgen/ir/derive.rs b/bindgen/ir/derive.rs new file mode 100644 index 0000000000..3ee6476af9 --- /dev/null +++ b/bindgen/ir/derive.rs @@ -0,0 +1,130 @@ +//! Traits for determining whether we can derive traits for a thing or not. +//! +//! These traits tend to come in pairs: +//! +//! 1. A "trivial" version, whose implementations aren't allowed to recursively +//! look at other types or the results of fix point analyses. +//! +//! 2. A "normal" version, whose implementations simply query the results of a +//! fix point analysis. +//! +//! The former is used by the analyses when creating the results queried by the +//! second. + +use super::context::BindgenContext; + +use std::cmp; +use std::ops; + +/// A trait that encapsulates the logic for whether or not we can derive `Debug` +/// for a given thing. +pub(crate) trait CanDeriveDebug { + /// Return `true` if `Debug` can be derived for this thing, `false` + /// otherwise. + fn can_derive_debug(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive `Copy` +/// for a given thing. +pub(crate) trait CanDeriveCopy { + /// Return `true` if `Copy` can be derived for this thing, `false` + /// otherwise. + fn can_derive_copy(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive +/// `Default` for a given thing. +pub(crate) trait CanDeriveDefault { + /// Return `true` if `Default` can be derived for this thing, `false` + /// otherwise. + fn can_derive_default(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive `Hash` +/// for a given thing. +pub(crate) trait CanDeriveHash { + /// Return `true` if `Hash` can be derived for this thing, `false` + /// otherwise. + fn can_derive_hash(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive +/// `PartialEq` for a given thing. +pub(crate) trait CanDerivePartialEq { + /// Return `true` if `PartialEq` can be derived for this thing, `false` + /// otherwise. + fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive +/// `PartialOrd` for a given thing. +pub(crate) trait CanDerivePartialOrd { + /// Return `true` if `PartialOrd` can be derived for this thing, `false` + /// otherwise. + fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive `Eq` +/// for a given thing. +pub(crate) trait CanDeriveEq { + /// Return `true` if `Eq` can be derived for this thing, `false` otherwise. + fn can_derive_eq(&self, ctx: &BindgenContext) -> bool; +} + +/// A trait that encapsulates the logic for whether or not we can derive `Ord` +/// for a given thing. +pub(crate) trait CanDeriveOrd { + /// Return `true` if `Ord` can be derived for this thing, `false` otherwise. + fn can_derive_ord(&self, ctx: &BindgenContext) -> bool; +} + +/// Whether it is possible or not to automatically derive trait for an item. +/// +/// ```ignore +/// No +/// ^ +/// | +/// Manually +/// ^ +/// | +/// Yes +/// ``` +/// +/// Initially we assume that we can derive trait for all types and then +/// update our understanding as we learn more about each type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)] +pub enum CanDerive { + /// Yes, we can derive automatically. + #[default] + Yes, + + /// The only thing that stops us from automatically deriving is that + /// array with more than maximum number of elements is used. + /// + /// This means we probably can "manually" implement such trait. + Manually, + + /// No, we cannot. + No, +} + +impl CanDerive { + /// Take the least upper bound of `self` and `rhs`. + pub(crate) fn join(self, rhs: Self) -> Self { + cmp::max(self, rhs) + } +} + +impl ops::BitOr for CanDerive { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + self.join(rhs) + } +} + +impl ops::BitOrAssign for CanDerive { + fn bitor_assign(&mut self, rhs: Self) { + *self = self.join(rhs); + } +} diff --git a/src/ir/dot.rs b/bindgen/ir/dot.rs similarity index 89% rename from src/ir/dot.rs rename to bindgen/ir/dot.rs index f7d07f19e2..9bfc559f41 100644 --- a/src/ir/dot.rs +++ b/bindgen/ir/dot.rs @@ -8,7 +8,7 @@ use std::path::Path; /// A trait for anything that can write attributes as `` rows to a dot /// file. -pub trait DotAttributes { +pub(crate) trait DotAttributes { /// Write this thing's attributes to the given output. Each attribute must /// be its own `...`. fn dot_attributes( @@ -17,11 +17,11 @@ pub trait DotAttributes { out: &mut W, ) -> io::Result<()> where - W: io::Write; + W: Write; } /// Write a graphviz dot file containing our IR. -pub fn write_dot_file

(ctx: &BindgenContext, path: P) -> io::Result<()> +pub(crate) fn write_dot_file

(ctx: &BindgenContext, path: P) -> io::Result<()> where P: AsRef, { @@ -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/src/ir/enum_ty.rs b/bindgen/ir/enum_ty.rs similarity index 82% rename from src/ir/enum_ty.rs rename to bindgen/ir/enum_ty.rs index 97455c9123..9b08da3bce 100644 --- a/src/ir/enum_ty.rs +++ b/bindgen/ir/enum_ty.rs @@ -6,7 +6,7 @@ use super::item::Item; use super::ty::{Type, TypeKind}; use crate::clang; use crate::ir::annotations::Annotations; -use crate::parse::{ClangItemParser, ParseError}; +use crate::parse::ParseError; use crate::regex_set::RegexSet; /// An enum representing custom handling that can be given to a variant. @@ -22,7 +22,7 @@ pub enum EnumVariantCustomBehavior { /// A C/C++ enumeration. #[derive(Debug)] -pub struct Enum { +pub(crate) struct Enum { /// The representation used for this enum; it should be an `IntKind` type or /// an alias to one. /// @@ -36,27 +36,30 @@ pub struct Enum { impl Enum { /// Construct a new `Enum` with the given representation and variants. - pub fn new(repr: Option, variants: Vec) -> Self { + pub(crate) fn new( + repr: Option, + variants: Vec, + ) -> Self { Enum { repr, variants } } /// Get this enumeration's representation. - pub fn repr(&self) -> Option { + pub(crate) fn repr(&self) -> Option { self.repr } /// Get this enumeration's variants. - pub fn variants(&self) -> &[EnumVariant] { + pub(crate) fn variants(&self) -> &[EnumVariant] { &self.variants } /// Construct an enumeration from the given Clang type. - pub fn from_ty( + pub(crate) fn from_ty( ty: &clang::Type, 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); @@ -70,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:?}") } }); @@ -102,8 +105,8 @@ impl Enum { let name = cursor.spelling(); let annotations = Annotations::new(&cursor); let custom_behavior = ctx - .parse_callbacks() - .and_then(|callbacks| { + .options() + .last_callback(|callbacks| { callbacks .enum_variant_behavior(type_name, &name, val) }) @@ -119,8 +122,8 @@ impl Enum { }); let new_name = ctx - .parse_callbacks() - .and_then(|callbacks| { + .options() + .last_callback(|callbacks| { callbacks.enum_variant_name(type_name, &name, val) }) .or_else(|| { @@ -156,7 +159,7 @@ impl Enum { let path = item.path_for_allowlisting(ctx); let enum_ty = item.expect_type(); - if enums.matches(&path[1..].join("::")) { + if enums.matches(path[1..].join("::")) { return true; } @@ -165,11 +168,11 @@ impl Enum { return false; } - self.variants().iter().any(|v| enums.matches(&v.name())) + self.variants().iter().any(|v| enums.matches(v.name())) } /// Returns the final representation of the enum. - pub fn computed_enum_variation( + pub(crate) fn computed_enum_variation( &self, ctx: &BindgenContext, item: &Item, @@ -187,10 +190,25 @@ impl Enum { &ctx.options().bitfield_enums, item, ) { - EnumVariation::NewType { is_bitfield: true } + EnumVariation::NewType { + is_bitfield: true, + is_global: false, + } } else if self.is_matching_enum(ctx, &ctx.options().newtype_enums, item) { - EnumVariation::NewType { is_bitfield: false } + EnumVariation::NewType { + is_bitfield: false, + is_global: false, + } + } else if self.is_matching_enum( + ctx, + &ctx.options().newtype_global_enums, + item, + ) { + EnumVariation::NewType { + is_bitfield: false, + is_global: true, + } } else if self.is_matching_enum( ctx, &ctx.options().rustified_enums, @@ -221,7 +239,7 @@ impl Enum { /// A single enum variant, to be contained only in an enum. #[derive(Debug)] -pub struct EnumVariant { +pub(crate) struct EnumVariant { /// The name of the variant. name: String, @@ -253,7 +271,7 @@ pub enum EnumVariantValue { impl EnumVariant { /// Construct a new enumeration variant from the given parts. - pub fn new( + pub(crate) fn new( name: String, name_for_allowlisting: String, comment: Option, @@ -270,36 +288,34 @@ impl EnumVariant { } /// Get this variant's name. - pub fn name(&self) -> &str { + pub(crate) fn name(&self) -> &str { &self.name } /// Get this variant's name. - pub fn name_for_allowlisting(&self) -> &str { + pub(crate) fn name_for_allowlisting(&self) -> &str { &self.name_for_allowlisting } /// Get this variant's value. - pub fn val(&self) -> EnumVariantValue { + pub(crate) fn val(&self) -> EnumVariantValue { self.val } /// Get this variant's documentation. - pub fn comment(&self) -> Option<&str> { + pub(crate) fn comment(&self) -> Option<&str> { self.comment.as_deref() } /// Returns whether this variant should be enforced to be a constant by code /// generation. - pub fn force_constification(&self) -> bool { - self.custom_behavior - .map_or(false, |b| b == EnumVariantCustomBehavior::Constify) + pub(crate) fn force_constification(&self) -> bool { + self.custom_behavior == Some(EnumVariantCustomBehavior::Constify) } /// Returns whether the current variant should be hidden completely from the /// resulting rust enum. - pub fn hidden(&self) -> bool { - self.custom_behavior - .map_or(false, |b| b == EnumVariantCustomBehavior::Hide) + pub(crate) fn hidden(&self) -> bool { + self.custom_behavior == Some(EnumVariantCustomBehavior::Hide) } } diff --git a/bindgen/ir/function.rs b/bindgen/ir/function.rs new file mode 100644 index 0000000000..6f8c00fa89 --- /dev/null +++ b/bindgen/ir/function.rs @@ -0,0 +1,837 @@ +//! Intermediate representation for C/C++ functions and methods. + +use super::comp::MethodKind; +use super::context::{BindgenContext, TypeId}; +use super::dot::DotAttributes; +use super::item::Item; +use super::traversal::{EdgeKind, Trace, Tracer}; +use super::ty::TypeKind; +use crate::callbacks::{ItemInfo, ItemKind}; +use crate::clang::{self, ABIKind, Attribute}; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; +use clang_sys::CXCallingConv; + +use quote::TokenStreamExt; +use std::io; +use std::str::FromStr; + +const RUST_DERIVE_FUNPTR_LIMIT: usize = 12; + +/// What kind of function are we looking at? +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum FunctionKind { + /// A plain, free function. + Function, + /// A method of some kind. + Method(MethodKind), +} + +impl FunctionKind { + /// Given a clang cursor, return the kind of function it represents, or + /// `None` otherwise. + pub(crate) fn from_cursor(cursor: &clang::Cursor) -> Option { + // FIXME(emilio): Deduplicate logic with `ir::comp`. + Some(match cursor.kind() { + clang_sys::CXCursor_FunctionDecl => FunctionKind::Function, + clang_sys::CXCursor_Constructor => { + FunctionKind::Method(MethodKind::Constructor) + } + clang_sys::CXCursor_Destructor => { + FunctionKind::Method(if cursor.method_is_virtual() { + MethodKind::VirtualDestructor { + pure_virtual: cursor.method_is_pure_virtual(), + } + } else { + MethodKind::Destructor + }) + } + clang_sys::CXCursor_CXXMethod => { + if cursor.method_is_virtual() { + FunctionKind::Method(MethodKind::Virtual { + pure_virtual: cursor.method_is_pure_virtual(), + }) + } else if cursor.method_is_static() { + FunctionKind::Method(MethodKind::Static) + } else { + FunctionKind::Method(MethodKind::Normal) + } + } + _ => return None, + }) + } +} + +/// The style of linkage +#[derive(Debug, Clone, Copy)] +pub(crate) enum Linkage { + /// Externally visible and can be linked against + External, + /// Not exposed externally. 'static inline' functions will have this kind of linkage + Internal, +} + +/// A function declaration, with a signature, arguments, and argument names. +/// +/// The argument names vector must be the same length as the ones in the +/// signature. +#[derive(Debug)] +pub(crate) struct Function { + /// The name of this function. + name: String, + + /// The mangled name, that is, the symbol. + mangled_name: Option, + + /// The link name. If specified, overwrite `mangled_name`. + link_name: Option, + + /// The ID pointing to the current function signature. + signature: TypeId, + + /// The kind of function this is. + kind: FunctionKind, + + /// The linkage of the function. + linkage: Linkage, +} + +impl Function { + /// Construct a new function. + pub(crate) fn new( + name: String, + mangled_name: Option, + link_name: Option, + signature: TypeId, + kind: FunctionKind, + linkage: Linkage, + ) -> Self { + Function { + name, + mangled_name, + link_name, + signature, + kind, + linkage, + } + } + + /// Get this function's name. + pub(crate) fn name(&self) -> &str { + &self.name + } + + /// Get this function's name. + pub(crate) fn mangled_name(&self) -> Option<&str> { + self.mangled_name.as_deref() + } + + /// Get this function's link name. + pub fn link_name(&self) -> Option<&str> { + self.link_name.as_deref() + } + + /// Get this function's signature type. + pub(crate) fn signature(&self) -> TypeId { + self.signature + } + + /// Get this function's kind. + pub(crate) fn kind(&self) -> FunctionKind { + self.kind + } + + /// Get this function's linkage. + pub(crate) fn linkage(&self) -> Linkage { + self.linkage + } +} + +impl DotAttributes for Function { + fn dot_attributes( + &self, + _ctx: &BindgenContext, + out: &mut W, + ) -> io::Result<()> + where + W: io::Write, + { + 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}")?; + } + + Ok(()) + } +} + +/// A valid rust ABI. +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub enum Abi { + /// The default C ABI. + C, + /// The "stdcall" ABI. + Stdcall, + /// The "efiapi" ABI. + EfiApi, + /// The "fastcall" ABI. + Fastcall, + /// The "thiscall" ABI. + ThisCall, + /// The "vectorcall" ABI. + Vectorcall, + /// The "aapcs" ABI. + Aapcs, + /// The "win64" ABI. + Win64, + /// The "C-unwind" ABI. + CUnwind, + /// The "system" ABI. + System, +} + +impl FromStr for Abi { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "C" => Ok(Self::C), + "stdcall" => Ok(Self::Stdcall), + "efiapi" => Ok(Self::EfiApi), + "fastcall" => Ok(Self::Fastcall), + "thiscall" => Ok(Self::ThisCall), + "vectorcall" => Ok(Self::Vectorcall), + "aapcs" => Ok(Self::Aapcs), + "win64" => Ok(Self::Win64), + "C-unwind" => Ok(Self::CUnwind), + "system" => Ok(Self::System), + _ => Err(format!("Invalid or unknown ABI {s:?}")), + } + } +} + +impl std::fmt::Display for Abi { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match *self { + Self::C => "C", + Self::Stdcall => "stdcall", + Self::EfiApi => "efiapi", + Self::Fastcall => "fastcall", + Self::ThisCall => "thiscall", + Self::Vectorcall => "vectorcall", + Self::Aapcs => "aapcs", + Self::Win64 => "win64", + Self::CUnwind => "C-unwind", + Abi::System => "system", + }; + + s.fmt(f) + } +} + +impl quote::ToTokens for Abi { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let abi = self.to_string(); + tokens.append_all(quote! { #abi }); + } +} + +/// An ABI extracted from a clang cursor. +#[derive(Debug, Copy, Clone)] +pub(crate) enum ClangAbi { + /// An ABI known by Rust. + Known(Abi), + /// An unknown or invalid ABI. + Unknown(CXCallingConv), +} + +impl ClangAbi { + /// Returns whether this Abi is known or not. + fn is_unknown(self) -> bool { + matches!(self, ClangAbi::Unknown(..)) + } +} + +impl quote::ToTokens for ClangAbi { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match *self { + Self::Known(abi) => abi.to_tokens(tokens), + Self::Unknown(cc) => panic!( + "Cannot turn unknown calling convention to tokens: {cc:?}" + ), + } + } +} + +/// A function signature. +#[derive(Debug)] +pub(crate) struct FunctionSig { + /// The name of this function signature. + name: String, + + /// The return type of the function. + return_type: TypeId, + + /// The type of the arguments, optionally with the name of the argument when + /// declared. + argument_types: Vec<(Option, TypeId)>, + + /// Whether this function is variadic. + is_variadic: bool, + is_divergent: bool, + + /// Whether this function's return value must be used. + must_use: bool, + + /// The ABI of this function. + abi: ClangAbi, +} + +fn get_abi(cc: CXCallingConv) -> ClangAbi { + use clang_sys::*; + match cc { + 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 | CXCallingConv_AArch64VectorCall => { + ClangAbi::Known(Abi::Vectorcall) + } + CXCallingConv_AAPCS => ClangAbi::Known(Abi::Aapcs), + CXCallingConv_X86_64Win64 => ClangAbi::Known(Abi::Win64), + other => ClangAbi::Unknown(other), + } +} + +/// Get the mangled name for the cursor's referent. +pub(crate) fn cursor_mangling( + ctx: &BindgenContext, + cursor: &clang::Cursor, +) -> Option { + if !ctx.options().enable_mangling { + return None; + } + + // We early return here because libclang may crash in some case + // if we pass in a variable inside a partial specialized template. + // See rust-lang/rust-bindgen#67, and rust-lang/rust-bindgen#462. + if cursor.is_in_non_fully_specialized_template() { + return None; + } + + let is_itanium_abi = ctx.abi_kind() == ABIKind::GenericItanium; + let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor; + if let Ok(mut manglings) = cursor.cxx_manglings() { + while let Some(m) = manglings.pop() { + // Only generate the destructor group 1, see below. + if is_itanium_abi && is_destructor && !m.ends_with("D1Ev") { + continue; + } + + return Some(m); + } + } + + let mut mangling = cursor.mangling(); + if mangling.is_empty() { + return None; + } + + if is_itanium_abi && is_destructor { + // With old (3.8-) libclang versions, and the Itanium ABI, clang returns + // the "destructor group 0" symbol, which means that it'll try to free + // memory, which definitely isn't what we want. + // + // Explicitly force the destructor group 1 symbol. + // + // See http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling-special + // for the reference, and http://stackoverflow.com/a/6614369/1091587 for + // a more friendly explanation. + // + // We don't need to do this for constructors since clang seems to always + // have returned the C1 constructor. + // + // FIXME(emilio): Can a legit symbol in other ABIs end with this string? + // I don't think so, but if it can this would become a linker error + // anyway, not an invalid free at runtime. + // + // TODO(emilio, #611): Use cpp_demangle if this becomes nastier with + // time. + if mangling.ends_with("D0Ev") { + let new_len = mangling.len() - 4; + mangling.truncate(new_len); + mangling.push_str("D1Ev"); + } + } + + Some(mangling) +} + +fn args_from_ty_and_cursor( + ty: &clang::Type, + cursor: &clang::Cursor, + ctx: &mut BindgenContext, +) -> Vec<(Option, TypeId)> { + let cursor_args = cursor.args().unwrap_or_default().into_iter(); + let type_args = ty.args().unwrap_or_default().into_iter(); + + // Argument types can be found in either the cursor or the type, but argument names may only be + // found on the cursor. We often have access to both a type and a cursor for each argument, but + // in some cases we may only have one. + // + // Prefer using the type as the source of truth for the argument's type, but fall back to + // inspecting the cursor (this happens for Objective C interfaces). + // + // Prefer using the cursor for the argument's type, but fall back to using the parent's cursor + // (this happens for function pointer return types). + cursor_args + .map(Some) + .chain(std::iter::repeat(None)) + .zip(type_args.map(Some).chain(std::iter::repeat(None))) + .take_while(|(cur, ty)| cur.is_some() || ty.is_some()) + .map(|(arg_cur, arg_ty)| { + let name = arg_cur.map(|a| a.spelling()).and_then(|name| { + if name.is_empty() { + None + } else { + Some(name) + } + }); + + let cursor = arg_cur.unwrap_or(*cursor); + let ty = arg_ty.unwrap_or_else(|| cursor.cur_type()); + (name, Item::from_ty_or_ref(ty, cursor, None, ctx)) + }) + .collect() +} + +impl FunctionSig { + /// Get the function name. + pub(crate) fn name(&self) -> &str { + &self.name + } + + /// Construct a new function signature from the given Clang type. + pub(crate) fn from_ty( + ty: &clang::Type, + cursor: &clang::Cursor, + ctx: &mut BindgenContext, + ) -> Result { + use clang_sys::*; + debug!("FunctionSig::from_ty {ty:?} {cursor:?}"); + + // Skip function templates + let kind = cursor.kind(); + if kind == CXCursor_FunctionTemplate { + return Err(ParseError::Continue); + } + + let spelling = cursor.spelling(); + + // Don't parse operatorxx functions in C++ + let is_operator = |spelling: &str| { + spelling.starts_with("operator") && + !clang::is_valid_identifier(spelling) + }; + if is_operator(&spelling) && !ctx.options().represent_cxx_operators { + return Err(ParseError::Continue); + } + + // Constructors of non-type template parameter classes for some reason + // include the template parameter in their name. Just skip them, since + // we don't handle well non-type template parameters anyway. + if (kind == CXCursor_Constructor || kind == CXCursor_Destructor) && + spelling.contains('<') + { + return Err(ParseError::Continue); + } + + let cursor = if cursor.is_valid() { + *cursor + } else { + ty.declaration() + }; + + let mut args = match kind { + CXCursor_FunctionDecl | + CXCursor_Constructor | + CXCursor_CXXMethod | + CXCursor_ObjCInstanceMethodDecl | + CXCursor_ObjCClassMethodDecl => { + args_from_ty_and_cursor(ty, &cursor, ctx) + } + _ => { + // For non-CXCursor_FunctionDecl, visiting the cursor's children + // is the only reliable way to get parameter names. + let mut args = vec![]; + cursor.visit(|c| { + if c.kind() == CXCursor_ParmDecl { + let ty = + Item::from_ty_or_ref(c.cur_type(), c, None, ctx); + let name = c.spelling(); + let name = + if name.is_empty() { None } else { Some(name) }; + args.push((name, ty)); + } + CXChildVisit_Continue + }); + + if args.is_empty() { + // FIXME(emilio): Sometimes libclang doesn't expose the + // right AST for functions tagged as stdcall and such... + // + // https://bugs.llvm.org/show_bug.cgi?id=45919 + args_from_ty_and_cursor(ty, &cursor, ctx) + } else { + args + } + } + }; + + let (must_use, mut is_divergent) = + if ctx.options().enable_function_attribute_detection { + let [must_use, no_return, no_return_cpp] = cursor.has_attrs(&[ + Attribute::MUST_USE, + Attribute::NO_RETURN, + Attribute::NO_RETURN_CPP, + ]); + (must_use, no_return || no_return_cpp) + } else { + Default::default() + }; + + // Check if the type contains __attribute__((noreturn)) outside of parentheses. This is + // somewhat fragile, but it seems to be the only way to get at this information as of + // libclang 9. + let ty_spelling = ty.spelling(); + let has_attribute_noreturn = ty_spelling + .match_indices("__attribute__((noreturn))") + .any(|(i, _)| { + let depth = ty_spelling[..i] + .bytes() + .filter_map(|ch| match ch { + b'(' => Some(1), + b')' => Some(-1), + _ => None, + }) + .sum::(); + depth == 0 + }); + is_divergent = is_divergent || has_attribute_noreturn; + + let is_method = kind == CXCursor_CXXMethod; + let is_constructor = kind == CXCursor_Constructor; + let is_destructor = kind == CXCursor_Destructor; + if (is_constructor || is_destructor || is_method) && + cursor.lexical_parent() != cursor.semantic_parent() + { + // Only parse constructors once. + return Err(ParseError::Continue); + } + + if is_method || is_constructor || is_destructor { + 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 || + 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"); + // The `class` most likely is not finished parsing yet, so use + // the unchecked variant. + let class = class.as_type_id_unchecked(); + + let class = if is_const { + let const_class_id = ctx.next_item_id(); + ctx.build_const_wrapper( + const_class_id, + class, + None, + &parent.cur_type(), + ) + } else { + class + }; + + let ptr = + Item::builtin_type(TypeKind::Pointer(class), false, ctx); + args.insert(0, (Some("this".into()), ptr)); + } else if is_virtual { + let void = Item::builtin_type(TypeKind::Void, false, ctx); + let ptr = + Item::builtin_type(TypeKind::Pointer(void), false, ctx); + args.insert(0, (Some("this".into()), ptr)); + } + } + + let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl || + kind == CXCursor_ObjCClassMethodDecl + { + ty.ret_type() + .or_else(|| cursor.ret_type()) + .ok_or(ParseError::Continue)? + } else { + ty.ret_type().ok_or(ParseError::Continue)? + }; + + let ret = if is_constructor && ctx.is_target_wasm32() { + // Constructors in Clang wasm32 target return a pointer to the object + // being constructed. + let void = Item::builtin_type(TypeKind::Void, false, ctx); + Item::builtin_type(TypeKind::Pointer(void), false, ctx) + } else { + Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx) + }; + + // Clang plays with us at "find the calling convention", see #549 and + // co. This seems to be a better fix than that commit. + let mut call_conv = ty.call_conv(); + if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() { + let cursor_call_conv = ty.call_conv(); + if cursor_call_conv != CXCallingConv_Invalid { + call_conv = cursor_call_conv; + } + } + + let abi = get_abi(call_conv); + + if abi.is_unknown() { + warn!("Unknown calling convention: {call_conv:?}"); + } + + Ok(Self { + name: spelling, + return_type: ret, + argument_types: args, + is_variadic: ty.is_variadic(), + is_divergent, + must_use, + abi, + }) + } + + /// Get this function signature's return type. + pub(crate) fn return_type(&self) -> TypeId { + self.return_type + } + + /// Get this function signature's argument (name, type) pairs. + pub(crate) fn argument_types(&self) -> &[(Option, TypeId)] { + &self.argument_types + } + + /// Get this function signature's ABI. + pub(crate) fn abi( + &self, + ctx: &BindgenContext, + name: Option<&str>, + ) -> crate::codegen::error::Result { + // FIXME (pvdrz): Try to do this check lazily instead. Maybe store the ABI inside `ctx` + // instead?. + let abi = if let Some(name) = name { + if let Some((abi, _)) = ctx + .options() + .abi_overrides + .iter() + .find(|(_, regex_set)| regex_set.matches(name)) + { + ClangAbi::Known(*abi) + } else { + self.abi + } + } else if let Some((abi, _)) = ctx + .options() + .abi_overrides + .iter() + .find(|(_, regex_set)| regex_set.matches(&self.name)) + { + ClangAbi::Known(*abi) + } else { + self.abi + }; + + match abi { + ClangAbi::Known(Abi::ThisCall) + if !ctx.options().rust_features().thiscall_abi => + { + Err(crate::codegen::error::Error::UnsupportedAbi("thiscall")) + } + ClangAbi::Known(Abi::Vectorcall) + if !ctx.options().rust_features().vectorcall_abi => + { + Err(crate::codegen::error::Error::UnsupportedAbi("vectorcall")) + } + ClangAbi::Known(Abi::CUnwind) + if !ctx.options().rust_features().c_unwind_abi => + { + Err(crate::codegen::error::Error::UnsupportedAbi("C-unwind")) + } + ClangAbi::Known(Abi::EfiApi) + if !ctx.options().rust_features().abi_efiapi => + { + Err(crate::codegen::error::Error::UnsupportedAbi("efiapi")) + } + ClangAbi::Known(Abi::Win64) if self.is_variadic() => { + Err(crate::codegen::error::Error::UnsupportedAbi("Win64")) + } + abi => Ok(abi), + } + } + + /// Is this function signature variadic? + pub(crate) fn is_variadic(&self) -> bool { + // Clang reports some functions as variadic when they *might* be + // variadic. We do the argument check because rust doesn't codegen well + // variadic functions without an initial argument. + self.is_variadic && !self.argument_types.is_empty() + } + + /// Must this function's return value be used? + pub(crate) fn must_use(&self) -> bool { + self.must_use + } + + /// Are function pointers with this signature able to derive Rust traits? + /// Rust only supports deriving traits for function pointers with a limited + /// number of parameters and a couple ABIs. + /// + /// For more details, see: + /// + /// * , + /// * , + /// * and + pub(crate) fn function_pointers_can_derive(&self) -> bool { + if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT { + return false; + } + + matches!(self.abi, ClangAbi::Known(Abi::C) | ClangAbi::Unknown(..)) + } + + /// Whether this function has attributes marking it as divergent. + pub(crate) fn is_divergent(&self) -> bool { + self.is_divergent + } +} + +impl ClangSubItemParser for Function { + fn parse( + cursor: clang::Cursor, + context: &mut BindgenContext, + ) -> Result, ParseError> { + use clang_sys::*; + + let Some(kind) = FunctionKind::from_cursor(&cursor) else { + return Err(ParseError::Continue); + }; + + 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 && + !context.options().generate_private_functions + { + return Err(ParseError::Continue); + } + + let linkage = cursor.linkage(); + let linkage = match linkage { + CXLinkage_External | CXLinkage_UniqueExternal => Linkage::External, + CXLinkage_Internal => Linkage::Internal, + _ => return Err(ParseError::Continue), + }; + + if cursor.is_inlined_function() || + cursor.definition().is_some_and(|x| x.is_inlined_function()) + { + if !context.options().generate_inline_functions && + !context.options().wrap_static_fns + { + return Err(ParseError::Continue); + } + + if cursor.is_deleted_function() && + !context.options().generate_deleted_functions + { + return Err(ParseError::Continue); + } + + // We cannot handle `inline` functions that are not `static`. + if context.options().wrap_static_fns && + cursor.is_inlined_function() && + matches!(linkage, Linkage::External) + { + return Err(ParseError::Continue); + } + } + + // Grab the signature using Item::from_ty. + let sig = Item::from_ty(&cursor.cur_type(), cursor, None, context)?; + + let mut name = cursor.spelling(); + assert!(!name.is_empty(), "Empty function name?"); + + if cursor.kind() == CXCursor_Destructor { + // Remove the leading `~`. The alternative to this is special-casing + // code-generation for destructor functions, which seems less than + // ideal. + if name.starts_with('~') { + name.remove(0); + } + + // Add a suffix to avoid colliding with constructors. This would be + // technically fine (since we handle duplicated functions/methods), + // but seems easy enough to handle it here. + name.push_str("_destructor"); + } + if let Some(nm) = context.options().last_callback(|callbacks| { + callbacks.generated_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Function, + }) + }) { + name = nm; + } + assert!(!name.is_empty(), "Empty function name."); + + let mangled_name = cursor_mangling(context, &cursor); + + let link_name = context.options().last_callback(|callbacks| { + callbacks.generated_link_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Function, + }) + }); + + let function = Self::new( + name.clone(), + mangled_name, + link_name, + sig, + kind, + linkage, + ); + + Ok(ParseResult::New(function, Some(cursor))) + } +} + +impl Trace for FunctionSig { + type Extra = (); + + fn trace(&self, _: &BindgenContext, tracer: &mut T, _: &()) + where + T: Tracer, + { + tracer.visit_kind(self.return_type().into(), EdgeKind::FunctionReturn); + + for &(_, ty) in self.argument_types() { + tracer.visit_kind(ty.into(), EdgeKind::FunctionParameter); + } + } +} diff --git a/src/ir/int.rs b/bindgen/ir/int.rs similarity index 83% rename from src/ir/int.rs rename to bindgen/ir/int.rs index 22838e897c..217fc11efa 100644 --- a/src/ir/int.rs +++ b/bindgen/ir/int.rs @@ -12,7 +12,7 @@ pub enum IntKind { /// An `unsigned char`. UChar, - /// An `wchar_t`. + /// A `wchar_t`. WChar, /// A platform-dependent `char` type, with the signedness support. @@ -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, @@ -87,41 +90,34 @@ pub enum IntKind { impl IntKind { /// Is this integral type signed? - pub fn is_signed(&self) -> bool { + pub(crate) fn is_signed(&self) -> bool { use self::IntKind::*; match *self { // TODO(emilio): wchar_t can in theory be signed, but we have no way // 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, } } /// If this type has a known size, return it (in bytes). This is to /// alleviate libclang sometimes not giving us a layout (like in the case /// when an enum is defined inside a class with template parameters). - pub fn known_size(&self) -> Option { + pub(crate) fn known_size(&self) -> Option { 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 fn signedness_matches(&self, val: i64) -> bool { - val >= 0 || self.is_signed() - } } diff --git a/src/ir/item.rs b/bindgen/ir/item.rs similarity index 83% rename from src/ir/item.rs rename to bindgen/ir/item.rs index aed575ca11..eea02cce6c 100644 --- a/src/ir/item.rs +++ b/bindgen/ir/item.rs @@ -1,9 +1,10 @@ //! 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::comment; use super::comp::{CompKind, MethodKind}; use super::context::{BindgenContext, ItemId, PartialType, TypeId}; use super::derive::{ @@ -13,23 +14,20 @@ 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::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; -use clang_sys; -use lazycell::LazyCell; -use regex; -use std::cell::Cell; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; + +use std::cell::{Cell, OnceCell}; use std::collections::BTreeSet; use std::fmt::Write; use std::io; use std::iter; +use std::sync::OnceLock; /// A trait to get the canonical name from an item. /// @@ -41,14 +39,14 @@ use std::iter; /// /// This name is required to be safe for Rust, that is, is not expected to /// return any rust keyword from here. -pub trait ItemCanonicalName { +pub(crate) trait ItemCanonicalName { /// Get the canonical name for this item. fn canonical_name(&self, ctx: &BindgenContext) -> String; } /// 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 { @@ -58,7 +56,7 @@ pub trait ItemCanonicalName { /// /// For bar, the canonical path is `vec!["foo", "BAR"]`, while the canonical /// name is just `"BAR"`. -pub trait ItemCanonicalPath { +pub(crate) trait ItemCanonicalPath { /// Get the namespace-aware canonical path for this item. This means that if /// namespaces are disabled, you'll get a single item, and otherwise you get /// the whole path. @@ -72,7 +70,7 @@ pub trait ItemCanonicalPath { } /// A trait for determining if some IR thing is opaque or not. -pub trait IsOpaque { +pub(crate) trait IsOpaque { /// Extra context the IR thing needs to determine if it is opaque or not. type Extra; @@ -83,36 +81,31 @@ pub trait IsOpaque { } /// A trait for determining if some IR thing has type parameter in array or not. -pub trait HasTypeParamInArray { +pub(crate) trait HasTypeParamInArray { /// Returns `true` if the thing has Array, and `false` otherwise. fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool; } -/// A trait for determining if some IR thing has float or not. -pub trait HasFloat { - /// Returns `true` if the thing has float, and `false` otherwise. - fn has_float(&self, ctx: &BindgenContext) -> bool; -} - /// A trait for iterating over an item and its parents and up its ancestor chain /// up to (but not including) the implicit root module. -pub trait ItemAncestors { +pub(crate) trait ItemAncestors { /// Get an iterable over this item's ancestors. fn ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>; } -#[cfg(testing_only_extra_assertions)] +#[cfg(feature = "__testing_only_extra_assertions")] type DebugOnlyItemSet = ItemSet; -#[cfg(not(testing_only_extra_assertions))] +#[cfg(not(feature = "__testing_only_extra_assertions"))] struct DebugOnlyItemSet; -#[cfg(not(testing_only_extra_assertions))] +#[cfg(not(feature = "__testing_only_extra_assertions"))] impl DebugOnlyItemSet { fn new() -> Self { DebugOnlyItemSet } + #[allow(clippy::trivially_copy_pass_by_ref)] fn contains(&self, _id: &ItemId) -> bool { false } @@ -121,7 +114,7 @@ impl DebugOnlyItemSet { } /// An iterator over an item and its ancestors. -pub struct ItemAncestorsIter<'a> { +pub(crate) struct ItemAncestorsIter<'a> { item: ItemId, ctx: &'a BindgenContext, seen: DebugOnlyItemSet, @@ -137,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 { @@ -365,7 +358,7 @@ impl CanDeriveOrd for Item { /// information). /// /// Items refer to each other by `ItemId`. Every item has its parent's -/// id. Depending on the kind of item this is, it may also refer to other items, +/// ID. Depending on the kind of item this is, it may also refer to other items, /// such as a compound type item referring to other types. Collectively, these /// references form a graph. /// @@ -378,42 +371,42 @@ impl CanDeriveOrd for Item { /// all of them apply to every item. Those rules are described in the /// `annotations` module. #[derive(Debug)] -pub struct Item { - /// This item's id. +pub(crate) struct Item { + /// This item's ID. id: ItemId, - /// The item's local id, unique only amongst its siblings. Only used for + /// 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 + /// Note that only structs, unions, and enums get a local type ID. In any /// case this is an implementation detail. - local_id: LazyCell, + local_id: OnceCell, - /// The next local id to use for a child or template instantiation. + /// The next local ID to use for a child or template instantiation. next_child_local_id: Cell, /// A cached copy of the canonical name, as returned by `canonical_name`. /// /// This is a fairly used operation during codegen so this makes bindgen /// considerably faster in those cases. - canonical_name: LazyCell, + canonical_name: OnceCell, /// The path to use for allowlisting and other name-based checks, as /// returned by `path_for_allowlisting`, lazily constructed. - path_for_allowlisting: LazyCell>, + path_for_allowlisting: OnceCell>, /// A doc comment over the item, if any. comment: Option, /// Annotations extracted from the doc comment, or the default ones /// otherwise. annotations: Annotations, - /// An item's parent id. This will most likely be a class where this item + /// An item's parent ID. This will most likely be a class where this item /// was declared, or a module, etc. /// /// All the items have a parent, except the root module, in which case the - /// parent id is its own id. + /// parent ID is its own ID. parent_id: ItemId, /// The item kind. kind: ItemKind, @@ -429,7 +422,7 @@ impl AsRef for Item { impl Item { /// Construct a new `Item`. - pub fn new( + pub(crate) fn new( id: ItemId, comment: Option, annotations: Option, @@ -440,10 +433,10 @@ impl Item { debug_assert!(id != parent_id || kind.is_module()); Item { id, - local_id: LazyCell::new(), + local_id: OnceCell::new(), next_child_local_id: Cell::new(1), - canonical_name: LazyCell::new(), - path_for_allowlisting: LazyCell::new(), + canonical_name: OnceCell::new(), + path_for_allowlisting: OnceCell::new(), parent_id, comment, annotations: annotations.unwrap_or_default(), @@ -453,13 +446,13 @@ impl Item { } /// Construct a new opaque item type. - pub fn new_opaque_type( + pub(crate) fn new_opaque_type( with_id: ItemId, ty: &clang::Type, 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( @@ -471,35 +464,38 @@ impl Item { } /// Get this `Item`'s identifier. - pub fn id(&self) -> ItemId { + pub(crate) fn id(&self) -> ItemId { self.id } /// Get this `Item`'s parent's identifier. /// /// For the root module, the parent's ID is its own ID. - pub fn parent_id(&self) -> ItemId { + pub(crate) fn parent_id(&self) -> ItemId { self.parent_id } - /// Set this item's parent id. + /// Set this item's parent ID. /// /// This is only used so replacements get generated in the proper module. - pub fn set_parent_for_replacement>(&mut self, id: Id) { + pub(crate) fn set_parent_for_replacement>( + &mut self, + id: Id, + ) { self.parent_id = id.into(); } /// Returns the depth this item is indented to. /// /// FIXME(emilio): This may need fixes for the enums within modules stuff. - pub fn codegen_depth(&self, ctx: &BindgenContext) -> usize { + pub(crate) fn codegen_depth(&self, ctx: &BindgenContext) -> usize { if !ctx.options().enable_cxx_namespaces { return 0; } 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 }) @@ -510,28 +506,28 @@ impl Item { /// Get this `Item`'s comment, if it has any, already preprocessed and with /// the right indentation. - pub fn comment(&self, ctx: &BindgenContext) -> Option { + pub(crate) fn comment(&self, ctx: &BindgenContext) -> Option { if !ctx.options().generate_comments { return None; } - self.comment.as_ref().map(|comment| { - comment::preprocess(comment, self.codegen_depth(ctx)) - }) + self.comment + .as_ref() + .map(|comment| ctx.options().process_comment(comment)) } /// What kind of item is this? - pub fn kind(&self) -> &ItemKind { + pub(crate) fn kind(&self) -> &ItemKind { &self.kind } /// Get a mutable reference to this item's kind. - pub fn kind_mut(&mut self) -> &mut ItemKind { + pub(crate) fn kind_mut(&mut self) -> &mut ItemKind { &mut self.kind } /// Where in the source is this item located? - pub fn location(&self) -> Option<&clang::SourceLocation> { + pub(crate) fn location(&self) -> Option<&clang::SourceLocation> { self.location.as_ref() } @@ -540,8 +536,8 @@ impl Item { /// This should stay relatively stable in the face of code motion outside or /// below this item's lexical scope, meaning that this can be useful for /// generating relatively stable identifiers within a scope. - pub fn local_id(&self, ctx: &BindgenContext) -> usize { - *self.local_id.borrow_with(|| { + pub(crate) fn local_id(&self, ctx: &BindgenContext) -> usize { + *self.local_id.get_or_init(|| { let parent = ctx.resolve_item(self.parent_id); parent.next_child_local_id() }) @@ -553,7 +549,7 @@ impl Item { /// This is currently used for anonymous items, and template instantiation /// tests, in both cases in order to reduce noise when system headers are at /// place. - pub fn next_child_local_id(&self) -> usize { + pub(crate) fn next_child_local_id(&self) -> usize { let local_id = self.next_child_local_id.get(); self.next_child_local_id.set(local_id + 1); local_id @@ -577,7 +573,7 @@ impl Item { /// This function is used to determine when the codegen phase should call /// `codegen` on an item, since any item that is not top-level will be /// generated by its parent. - pub fn is_toplevel(&self, ctx: &BindgenContext) -> bool { + pub(crate) fn is_toplevel(&self, ctx: &BindgenContext) -> bool { // FIXME: Workaround for some types falling behind when parsing weird // stl classes, for example. if ctx.options().enable_cxx_namespaces && @@ -589,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() { @@ -608,36 +603,36 @@ impl Item { /// Get a reference to this item's underlying `Type`. Panic if this is some /// other kind of item. - pub fn expect_type(&self) -> &Type { + pub(crate) fn expect_type(&self) -> &Type { self.kind().expect_type() } /// Get a reference to this item's underlying `Type`, or `None` if this is /// some other kind of item. - pub fn as_type(&self) -> Option<&Type> { + pub(crate) fn as_type(&self) -> Option<&Type> { self.kind().as_type() } /// Get a reference to this item's underlying `Function`. Panic if this is /// some other kind of item. - pub fn expect_function(&self) -> &Function { + pub(crate) fn expect_function(&self) -> &Function { self.kind().expect_function() } /// Is this item a module? - pub fn is_module(&self) -> bool { + pub(crate) fn is_module(&self) -> bool { matches!(self.kind, ItemKind::Module(..)) } /// Get this item's annotations. - pub fn annotations(&self) -> &Annotations { + pub(crate) fn annotations(&self) -> &Annotations { &self.annotations } /// Whether this item should be blocklisted. /// /// This may be due to either annotations or to other kind of configuration. - pub fn is_blocklisted(&self, ctx: &BindgenContext) -> bool { + pub(crate) fn is_blocklisted(&self, ctx: &BindgenContext) -> bool { debug_assert!( ctx.in_codegen_phase(), "You're not supposed to call this yet" @@ -650,7 +645,7 @@ impl Item { if let Some(location) = &self.location { let (file, _, _, _) = location.location(); if let Some(filename) = file.name() { - if ctx.options().blocklisted_files.matches(&filename) { + if ctx.options().blocklisted_files.matches(filename) { return true; } } @@ -668,27 +663,23 @@ impl Item { ItemKind::Function(..) => { ctx.options().blocklisted_functions.matches(&name) } - // TODO: Add constant / namespace blocklisting? - ItemKind::Var(..) | ItemKind::Module(..) => false, + ItemKind::Var(..) => { + ctx.options().blocklisted_vars.matches(&name) + } + // TODO: Add namespace blocklisting? + ItemKind::Module(..) => false, } } - /// Is this a reference to another type? - pub fn is_type_ref(&self) -> bool { - self.as_type().map_or(false, |ty| ty.is_type_ref()) - } - - /// Is this item a var type? - pub fn is_var(&self) -> bool { - matches!(*self.kind(), ItemKind::Var(..)) - } - - /// Take out item NameOptions - pub fn name<'a>(&'a self, ctx: &'a BindgenContext) -> NameOptions<'a> { + /// Take out item `NameOptions` + pub(crate) fn name<'a>( + &'a self, + ctx: &'a BindgenContext, + ) -> NameOptions<'a> { NameOptions::new(self, ctx) } - /// Get the target item id for name generation. + /// Get the target item ID for name generation. fn name_target(&self, ctx: &BindgenContext) -> ItemId { let mut targets_seen = DebugOnlyItemSet::new(); let mut item = self; @@ -718,14 +709,17 @@ impl Item { /// Create a fully disambiguated name for an item, including template /// parameters if it is a type - pub fn full_disambiguated_name(&self, ctx: &BindgenContext) -> String { + pub(crate) fn full_disambiguated_name( + &self, + ctx: &BindgenContext, + ) -> String { let mut s = String::new(); let level = 0; self.push_disambiguated_name(ctx, &mut s, level); s } - /// Helper function for full_disambiguated_name + /// Helper function for `full_disambiguated_name` fn push_disambiguated_name( &self, ctx: &BindgenContext, @@ -735,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() @@ -743,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}"); } } } @@ -794,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(); } } @@ -842,7 +834,7 @@ impl Item { /// If `BindgenOptions::disable_nested_struct_naming` is true then returned /// name is the inner most non-anonymous name plus all the anonymous base names /// that follows. - pub fn real_canonical_name( + pub(crate) fn real_canonical_name( &self, ctx: &BindgenContext, opt: &NameOptions, @@ -865,7 +857,7 @@ impl Item { return base_name; } - // Ancestors' id iter + // Ancestors' ID iter let mut ids_iter = target .parent_id() .ancestors(ctx) @@ -932,8 +924,19 @@ impl Item { let name = names.join("_"); let name = if opt.user_mangled == UserMangled::Yes { - ctx.parse_callbacks() - .and_then(|callbacks| callbacks.item_name(&name)) + 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(item_info)) .unwrap_or(name) } else { name @@ -942,30 +945,30 @@ impl Item { ctx.rust_mangle(&name).into_owned() } - /// The exposed id that represents an unique id among the siblings of a + /// The exposed ID that represents an unique ID among the siblings of a /// given item. - pub fn exposed_id(&self, ctx: &BindgenContext) -> String { + pub(crate) fn exposed_id(&self, ctx: &BindgenContext) -> String { // Only use local ids for enums, classes, structs and union types. All - // other items use their global id. + // other items use their global ID. let ty_kind = self.kind().as_type().map(|t| t.kind()); - if let Some(ty_kind) = ty_kind { - match *ty_kind { - TypeKind::Comp(..) | - TypeKind::TemplateInstantiation(..) | - TypeKind::Enum(..) => return self.local_id(ctx).to_string(), - _ => {} - } + if let Some( + TypeKind::Comp(..) | + TypeKind::TemplateInstantiation(..) | + TypeKind::Enum(..), + ) = ty_kind + { + return self.local_id(ctx).to_string(); } // Note that this `id_` prefix prevents (really unlikely) collisions - // between the global id and the local id of an item with the same + // between the global ID and the local ID of an item with the same // parent. format!("id_{}", self.id().as_usize()) } /// Get a reference to this item's `Module`, or `None` if this is not a /// `Module` item. - pub fn as_module(&self) -> Option<&Module> { + pub(crate) fn as_module(&self) -> Option<&Module> { match self.kind { ItemKind::Module(ref module) => Some(module), _ => None, @@ -974,7 +977,7 @@ impl Item { /// Get a mutable reference to this item's `Module`, or `None` if this is /// not a `Module` item. - pub fn as_module_mut(&mut self) -> Option<&mut Module> { + pub(crate) fn as_module_mut(&mut self) -> Option<&mut Module> { match self.kind { ItemKind::Module(ref mut module) => Some(module), _ => None, @@ -986,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() { @@ -1013,7 +1015,7 @@ impl Item { } /// Is this item of a kind that is enabled for code generation? - pub fn is_enabled_for_codegen(&self, ctx: &BindgenContext) -> bool { + pub(crate) fn is_enabled_for_codegen(&self, ctx: &BindgenContext) -> bool { let cc = &ctx.options().codegen_config; match *self.kind() { ItemKind::Module(..) => true, @@ -1024,24 +1026,27 @@ 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(), }, } } /// Returns the path we should use for allowlisting / blocklisting, which /// doesn't include user-mangling. - pub fn path_for_allowlisting(&self, ctx: &BindgenContext) -> &Vec { + pub(crate) fn path_for_allowlisting( + &self, + ctx: &BindgenContext, + ) -> &Vec { self.path_for_allowlisting - .borrow_with(|| self.compute_path(ctx, UserMangled::No)) + .get_or_init(|| self.compute_path(ctx, UserMangled::No)) } fn compute_path( @@ -1063,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 }) @@ -1082,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 +1100,25 @@ impl Item { _ => return None, }) } + + /// Whether this is a `#[must_use]` type. + 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) }) } @@ -1196,31 +1219,8 @@ impl HasTypeParamInArray for Item { } } -impl HasFloat for T -where - T: Copy + Into, -{ - fn has_float(&self, ctx: &BindgenContext) -> bool { - debug_assert!( - ctx.in_codegen_phase(), - "You're not supposed to call this yet" - ); - ctx.lookup_has_float(*self) - } -} - -impl HasFloat for Item { - fn has_float(&self, ctx: &BindgenContext) -> bool { - debug_assert!( - ctx.in_codegen_phase(), - "You're not supposed to call this yet" - ); - ctx.lookup_has_float(self.id()) - } -} - /// A set of items. -pub type ItemSet = BTreeSet; +pub(crate) type ItemSet = BTreeSet; impl DotAttributes for Item { fn dot_attributes( @@ -1303,8 +1303,9 @@ fn visit_child( } } -impl ClangItemParser for Item { - fn builtin_type( +impl Item { + /// Create a builtin type. + pub(crate) fn builtin_type( kind: TypeKind, is_const: bool, ctx: &mut BindgenContext, @@ -1329,7 +1330,8 @@ impl ClangItemParser for Item { id.as_type_id_unchecked() } - fn parse( + /// Parse this item from the given Clang cursor. + pub(crate) fn parse( cursor: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, @@ -1347,6 +1349,7 @@ impl ClangItemParser for Item { let current_module = ctx.current_module().into(); let relevant_parent_id = parent_id.unwrap_or(current_module); + #[allow(clippy::missing_docs_in_private_items)] macro_rules! try_parse { ($what:ident) => { match $what::parse(cursor, ctx) { @@ -1425,57 +1428,59 @@ impl ClangItemParser for Item { } } - // Guess how does clang treat extern "C" blocks? - if cursor.kind() == CXCursor_UnexposedDecl { - Err(ParseError::Recurse) - } else { + match cursor.kind() { + // On Clang 18+, extern "C" is reported accurately as a LinkageSpec. + // Older LLVM treat it as UnexposedDecl. + CXCursor_LinkageSpec | CXCursor_UnexposedDecl => { + Err(ParseError::Recurse) + } + // We allowlist cursors here known to be unhandled, to prevent being // too noisy about this. - match cursor.kind() { - CXCursor_MacroDefinition | - CXCursor_MacroExpansion | - CXCursor_UsingDeclaration | - CXCursor_UsingDirective | - CXCursor_StaticAssert | - CXCursor_FunctionTemplate => { - debug!( - "Unhandled cursor kind {:?}: {:?}", - cursor.kind(), - cursor - ); - } - CXCursor_InclusionDirective => { - let file = cursor.get_included_file_name(); - match file { - None => { - warn!( - "Inclusion of a nameless file in {:?}", - cursor - ); - } - Some(filename) => { - ctx.include_file(filename); - } + CXCursor_MacroDefinition | + CXCursor_MacroExpansion | + CXCursor_UsingDeclaration | + CXCursor_UsingDirective | + CXCursor_StaticAssert | + CXCursor_FunctionTemplate => { + debug!("Unhandled cursor kind {:?}: {cursor:?}", cursor.kind()); + Err(ParseError::Continue) + } + + CXCursor_InclusionDirective => { + let file = cursor.get_included_file_name(); + match file { + None => { + warn!("Inclusion of a nameless file in {cursor:?}"); } - } - _ => { - // ignore toplevel operator overloads - let spelling = cursor.spelling(); - if !spelling.starts_with("operator") { - warn!( - "Unhandled cursor kind {:?}: {:?}", - cursor.kind(), - cursor - ); + Some(included_file) => { + for cb in &ctx.options().parse_callbacks { + cb.include_file(&included_file); + } + + ctx.add_dep(included_file.into_boxed_str()); } } + Err(ParseError::Continue) } - Err(ParseError::Continue) + _ => { + // ignore toplevel operator overloads + let spelling = cursor.spelling(); + if !spelling.starts_with("operator") { + warn!( + "Unhandled cursor kind {:?}: {cursor:?}", + cursor.kind(), + ); + } + Err(ParseError::Continue) + } } } - fn from_ty_or_ref( + /// Parse this item from the given Clang type, or if we haven't resolved all + /// the other items this one depends on, an unresolved reference. + pub(crate) fn from_ty_or_ref( ty: clang::Type, location: clang::Cursor, parent_id: Option, @@ -1495,17 +1500,14 @@ impl ClangItemParser for Item { /// /// Typerefs are resolved once parsing is completely done, see /// `BindgenContext::resolve_typerefs`. - fn from_ty_or_ref_with_id( + pub(crate) fn from_ty_or_ref_with_id( potential_id: ItemId, ty: clang::Type, location: clang::Cursor, 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"); @@ -1525,11 +1527,11 @@ impl ClangItemParser for 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); @@ -1550,7 +1552,8 @@ impl ClangItemParser for Item { potential_id.as_type_id_unchecked() } - fn from_ty( + /// Parse this item from the given Clang type. See [`Item::from_ty_with_id`]. + pub(crate) fn from_ty( ty: &clang::Type, location: clang::Cursor, parent_id: Option, @@ -1563,12 +1566,12 @@ impl ClangItemParser for Item { /// This is one of the trickiest methods you'll find (probably along with /// some of the ones that handle templates in `BindgenContext`). /// - /// This method parses a type, given the potential id of that type (if + /// This method parses a type, given the potential ID of that type (if /// parsing it was correct), an optional location we're scanning, which is - /// critical some times to obtain information, an optional parent item id, - /// that will, if it's `None`, become the current module id, and the + /// critical some times to obtain information, an optional parent item ID, + /// that will, if it's `None`, become the current module ID, and the /// context. - fn from_ty_with_id( + pub(crate) fn from_ty_with_id( id: ItemId, ty: &clang::Type, location: clang::Cursor, @@ -1578,14 +1581,13 @@ impl ClangItemParser for 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() @@ -1605,7 +1607,7 @@ impl ClangItemParser for 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)); } } @@ -1615,7 +1617,8 @@ impl ClangItemParser for Item { canonical_def.unwrap_or_else(|| ty.declaration()) }; - let comment = 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)); @@ -1648,7 +1651,7 @@ impl ClangItemParser for 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()); } @@ -1714,13 +1717,11 @@ impl ClangItemParser for 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 } @@ -1735,10 +1736,9 @@ impl ClangItemParser for Item { ret } - /// A named type is a template parameter, e.g., the "T" in Foo. They're - /// always local so it's the only exception when there's no declaration for - /// a type. - fn type_param( + /// A named type is a template parameter, e.g., the `T` in `Foo`. They're always local so + /// it's the only exception when there's no declaration for a type. + pub(crate) fn type_param( with_id: Option, location: clang::Cursor, ctx: &mut BindgenContext, @@ -1747,13 +1747,10 @@ impl ClangItemParser for 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 { @@ -1815,10 +1812,10 @@ impl ClangItemParser for Item { refd: &clang::Cursor, spelling: &str, ) -> bool { - lazy_static! { - static ref ANON_TYPE_PARAM_RE: regex::Regex = - regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap(); - } + static ANON_TYPE_PARAM_RE: OnceLock = OnceLock::new(); + let anon_type_param_re = ANON_TYPE_PARAM_RE.get_or_init(|| { + regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap() + }); if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter { return false; @@ -1827,7 +1824,7 @@ impl ClangItemParser for Item { let refd_spelling = refd.spelling(); refd_spelling == spelling || // Allow for anonymous template parameters. - (refd_spelling.is_empty() && ANON_TYPE_PARAM_RE.is_match(spelling.as_ref())) + (refd_spelling.is_empty() && anon_type_param_re.is_match(spelling.as_ref())) } let definition = if is_template_with_spelling(&location, &ty_spelling) { @@ -1880,21 +1877,16 @@ impl ClangItemParser for 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 // tests/headers/variadic_tname.hpp. - let name = ty_spelling.replace("const ", "").replace(".", ""); + let name = ty_spelling.replace("const ", "").replace('.', ""); let id = with_id.unwrap_or_else(|| ctx.next_item_id()); let item = Item::new( @@ -1917,7 +1909,7 @@ impl ItemCanonicalName for Item { "You're not supposed to call this yet" ); self.canonical_name - .borrow_with(|| { + .get_or_init(|| { let in_namespace = ctx.options().enable_cxx_namespaces || ctx.options().disable_name_namespacing; @@ -1976,7 +1968,7 @@ enum UserMangled { /// Builder struct for naming variations, which hold inside different /// flags for naming options. #[derive(Debug)] -pub struct NameOptions<'a> { +pub(crate) struct NameOptions<'a> { item: &'a Item, ctx: &'a BindgenContext, within_namespaces: bool, @@ -1985,7 +1977,7 @@ pub struct NameOptions<'a> { impl<'a> NameOptions<'a> { /// Construct a new `NameOptions` - pub fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self { + pub(crate) fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self { NameOptions { item, ctx, @@ -1996,7 +1988,7 @@ impl<'a> NameOptions<'a> { /// Construct the name without the item's containing C++ namespaces mangled /// into it. In other words, the item's name within the item's namespace. - pub fn within_namespaces(&mut self) -> &mut Self { + pub(crate) fn within_namespaces(&mut self) -> &mut Self { self.within_namespaces = true; self } @@ -2007,7 +1999,7 @@ impl<'a> NameOptions<'a> { } /// Construct a name `String` - pub fn get(&self) -> String { + pub(crate) fn get(&self) -> String { self.item.real_canonical_name(self.ctx, self) } } diff --git a/bindgen/ir/item_kind.rs b/bindgen/ir/item_kind.rs new file mode 100644 index 0000000000..9221b50579 --- /dev/null +++ b/bindgen/ir/item_kind.rs @@ -0,0 +1,135 @@ +//! Different variants of an `Item` in our intermediate representation. + +use super::context::BindgenContext; +use super::dot::DotAttributes; +use super::function::Function; +use super::module::Module; +use super::ty::Type; +use super::var::Var; +use std::io; + +/// A item we parse and translate. +#[derive(Debug)] +pub(crate) enum ItemKind { + /// A module, created implicitly once (the root module), or via C++ + /// namespaces. + Module(Module), + + /// A type declared in any of the multiple ways it can be declared. + Type(Type), + + /// A function or method declaration. + Function(Function), + + /// A variable declaration, most likely a static. + Var(Var), +} + +impl ItemKind { + /// Get a reference to this `ItemKind`'s underlying `Module`, or `None` if it + /// is some other kind. + pub(crate) fn as_module(&self) -> Option<&Module> { + match *self { + ItemKind::Module(ref module) => Some(module), + _ => None, + } + } + + /// Transform our `ItemKind` into a string. + pub(crate) fn kind_name(&self) -> &'static str { + match *self { + ItemKind::Module(..) => "Module", + ItemKind::Type(..) => "Type", + ItemKind::Function(..) => "Function", + ItemKind::Var(..) => "Var", + } + } + + /// Is this a module? + pub(crate) fn is_module(&self) -> bool { + self.as_module().is_some() + } + + /// Get a reference to this `ItemKind`'s underlying `Function`, or `None` if + /// it is some other kind. + pub(crate) fn as_function(&self) -> Option<&Function> { + match *self { + ItemKind::Function(ref func) => Some(func), + _ => None, + } + } + + /// Is this a function? + pub(crate) fn is_function(&self) -> bool { + self.as_function().is_some() + } + + /// Get a reference to this `ItemKind`'s underlying `Function`, or panic if + /// it is some other kind. + pub(crate) fn expect_function(&self) -> &Function { + self.as_function().expect("Not a function") + } + + /// Get a reference to this `ItemKind`'s underlying `Type`, or `None` if + /// it is some other kind. + pub(crate) fn as_type(&self) -> Option<&Type> { + match *self { + ItemKind::Type(ref ty) => Some(ty), + _ => None, + } + } + + /// Get a mutable reference to this `ItemKind`'s underlying `Type`, or `None` + /// if it is some other kind. + pub(crate) fn as_type_mut(&mut self) -> Option<&mut Type> { + match *self { + ItemKind::Type(ref mut ty) => Some(ty), + _ => None, + } + } + + /// Is this a type? + pub(crate) fn is_type(&self) -> bool { + self.as_type().is_some() + } + + /// Get a reference to this `ItemKind`'s underlying `Type`, or panic if it is + /// some other kind. + pub(crate) fn expect_type(&self) -> &Type { + self.as_type().expect("Not a type") + } + + /// Get a reference to this `ItemKind`'s underlying `Var`, or `None` if it is + /// some other kind. + pub(crate) fn as_var(&self) -> Option<&Var> { + match *self { + ItemKind::Var(ref v) => Some(v), + _ => None, + } + } + + /// Is this a variable? + pub(crate) fn is_var(&self) -> bool { + self.as_var().is_some() + } +} + +impl DotAttributes for ItemKind { + fn dot_attributes( + &self, + ctx: &BindgenContext, + out: &mut W, + ) -> io::Result<()> + where + W: io::Write, + { + writeln!(out, "kind{}", self.kind_name())?; + + match *self { + ItemKind::Module(ref module) => module.dot_attributes(ctx, out), + ItemKind::Type(ref ty) => ty.dot_attributes(ctx, out), + ItemKind::Function(ref func) => func.dot_attributes(ctx, out), + ItemKind::Var(ref var) => var.dot_attributes(ctx, out), + } + } +} diff --git a/bindgen/ir/layout.rs b/bindgen/ir/layout.rs new file mode 100644 index 0000000000..ba570e3702 --- /dev/null +++ b/bindgen/ir/layout.rs @@ -0,0 +1,70 @@ +//! Intermediate representation for the physical layout of some type. + +use crate::ir::context::BindgenContext; + +/// A type that represents the struct layout of a type. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct Layout { + /// The size (in bytes) of this layout. + pub(crate) size: usize, + /// The alignment (in bytes) of this layout. + pub(crate) align: usize, + /// Whether this layout's members are packed or not. + pub(crate) packed: bool, +} + +#[test] +fn test_layout_for_size() { + 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) + ); + assert_eq!( + Layout::for_size_internal(ptr_size, 3 * ptr_size), + Layout::new(3 * ptr_size, ptr_size) + ); +} + +impl Layout { + /// Gets the integer type name for a given known size. + pub(crate) fn known_type_for_size(size: usize) -> Option { + Some(match size { + 16 => syn::parse_quote! { u128 }, + 8 => syn::parse_quote! { u64 }, + 4 => syn::parse_quote! { u32 }, + 2 => syn::parse_quote! { u16 }, + 1 => syn::parse_quote! { u8 }, + _ => return None, + }) + } + + /// Construct a new `Layout` with the given `size` and `align`. It is not + /// packed. + pub(crate) fn new(size: usize, align: usize) -> Self { + Layout { + size, + align, + packed: false, + } + } + + fn for_size_internal(ptr_size: usize, size: usize) -> Self { + let mut next_align = 2; + while size % next_align == 0 && next_align <= ptr_size { + next_align *= 2; + } + Layout { + size, + align: next_align / 2, + packed: false, + } + } + + /// Creates a non-packed layout for a given size, trying to use the maximum + /// alignment possible. + pub(crate) fn for_size(ctx: &BindgenContext, size: usize) -> Self { + Self::for_size_internal(ctx.target_pointer_size(), size) + } +} diff --git a/bindgen/ir/mod.rs b/bindgen/ir/mod.rs new file mode 100644 index 0000000000..acdb4896cd --- /dev/null +++ b/bindgen/ir/mod.rs @@ -0,0 +1,25 @@ +//! The ir module defines bindgen's intermediate representation. +//! +//! Parsing C/C++ generates the IR, while code generation outputs Rust code from +//! the IR. +#![deny(clippy::missing_docs_in_private_items)] + +pub(crate) mod analysis; +pub(crate) mod annotations; +pub(crate) mod comment; +pub(crate) mod comp; +pub(crate) mod context; +pub(crate) mod derive; +pub(crate) mod dot; +pub(crate) mod enum_ty; +pub(crate) mod function; +pub(crate) mod int; +pub(crate) mod item; +pub(crate) mod item_kind; +pub(crate) mod layout; +pub(crate) mod module; +pub(crate) mod objc; +pub(crate) mod template; +pub(crate) mod traversal; +pub(crate) mod ty; +pub(crate) mod var; diff --git a/src/ir/module.rs b/bindgen/ir/module.rs similarity index 80% rename from src/ir/module.rs rename to bindgen/ir/module.rs index d5aca94a6e..4788cf4285 100644 --- a/src/ir/module.rs +++ b/bindgen/ir/module.rs @@ -6,11 +6,12 @@ use super::item::ItemSet; use crate::clang; use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use crate::parse_one; + use std::io; /// Whether this module is inline or not. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum ModuleKind { +pub(crate) enum ModuleKind { /// This module is not inline. Normal, /// This module is inline, as in `inline namespace foo {}`. @@ -19,7 +20,7 @@ pub enum ModuleKind { /// A module, as in, a C++ namespace. #[derive(Clone, Debug)] -pub struct Module { +pub(crate) struct Module { /// The name of the module, or none if it's anonymous. name: Option, /// The kind of module this is. @@ -30,7 +31,7 @@ pub struct Module { impl Module { /// Construct a new `Module`. - pub fn new(name: Option, kind: ModuleKind) -> Self { + pub(crate) fn new(name: Option, kind: ModuleKind) -> Self { Module { name, kind, @@ -39,22 +40,22 @@ impl Module { } /// Get this module's name. - pub fn name(&self) -> Option<&str> { + pub(crate) fn name(&self) -> Option<&str> { self.name.as_deref() } /// Get a mutable reference to this module's children. - pub fn children_mut(&mut self) -> &mut ItemSet { + pub(crate) fn children_mut(&mut self) -> &mut ItemSet { &mut self.children } /// Get this module's children. - pub fn children(&self) -> &ItemSet { + pub(crate) fn children(&self) -> &ItemSet { &self.children } /// Whether this namespace is inline. - pub fn is_inline(&self) -> bool { + pub(crate) fn is_inline(&self) -> bool { self.kind == ModuleKind::Inline } } @@ -82,9 +83,9 @@ impl ClangSubItemParser for Module { CXCursor_Namespace => { let module_id = ctx.module(cursor); ctx.with_module(module_id, |ctx| { - cursor.visit(|cursor| { - parse_one(ctx, cursor, Some(module_id.into())) - }) + cursor.visit_sorted(ctx, |ctx, child| { + 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 new file mode 100644 index 0000000000..6cdadb131d --- /dev/null +++ b/bindgen/ir/objc.rs @@ -0,0 +1,343 @@ +//! Objective C types + +use super::context::{BindgenContext, ItemId}; +use super::function::FunctionSig; +use super::item::Item; +use super::traversal::{Trace, Tracer}; +use super::ty::TypeKind; +use crate::clang; +use clang_sys::CXChildVisit_Continue; +use clang_sys::CXCursor_ObjCCategoryDecl; +use clang_sys::CXCursor_ObjCClassMethodDecl; +use clang_sys::CXCursor_ObjCClassRef; +use clang_sys::CXCursor_ObjCInstanceMethodDecl; +use clang_sys::CXCursor_ObjCProtocolDecl; +use clang_sys::CXCursor_ObjCProtocolRef; +use clang_sys::CXCursor_ObjCSuperClassRef; +use clang_sys::CXCursor_TemplateTypeParameter; +use proc_macro2::{Ident, Span, TokenStream}; + +/// Objective-C interface as used in `TypeKind` +/// +/// Also, protocols and categories are parsed as this type +#[derive(Debug)] +pub(crate) struct ObjCInterface { + /// The name + /// like, `NSObject` + name: String, + + category: Option, + + is_protocol: bool, + + /// The list of template names almost always, `ObjectType` or `KeyType` + pub(crate) template_names: Vec, + + /// The list of protocols that this interface conforms to. + pub(crate) conforms_to: Vec, + + /// The direct parent for this interface. + pub(crate) parent_class: Option, + + /// List of the methods defined in this interface + methods: Vec, + + class_methods: Vec, +} + +/// The objective c methods +#[derive(Debug)] +pub(crate) struct ObjCMethod { + /// The original method selector name + /// like, dataWithBytes:length: + name: String, + + /// Method name as converted to rust + /// like, `dataWithBytes_length`_ + rust_name: String, + + signature: FunctionSig, + + /// Is class method? + is_class_method: bool, +} + +impl ObjCInterface { + fn new(name: &str) -> ObjCInterface { + ObjCInterface { + name: name.to_owned(), + category: None, + is_protocol: false, + template_names: Vec::new(), + parent_class: None, + conforms_to: Vec::new(), + methods: Vec::new(), + class_methods: Vec::new(), + } + } + + /// The name + /// 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` + pub(crate) fn rust_name(&self) -> String { + if let Some(ref cat) = self.category { + format!("{}_{cat}", self.name()) + } else if self.is_protocol { + format!("P{}", self.name()) + } else { + format!("I{}", self.name().to_owned()) + } + } + + /// Is this a template interface? + pub(crate) fn is_template(&self) -> bool { + !self.template_names.is_empty() + } + + /// List of the methods defined in this interface + pub(crate) fn methods(&self) -> &Vec { + &self.methods + } + + /// Is this a protocol? + pub(crate) fn is_protocol(&self) -> bool { + self.is_protocol + } + + /// Is this a category? + pub(crate) fn is_category(&self) -> bool { + self.category.is_some() + } + + /// List of the class methods defined in this interface + pub(crate) fn class_methods(&self) -> &Vec { + &self.class_methods + } + + /// Parses the Objective C interface from the cursor + pub(crate) fn from_ty( + cursor: &clang::Cursor, + ctx: &mut BindgenContext, + ) -> Option { + let name = cursor.spelling(); + let mut interface = Self::new(&name); + + if cursor.kind() == CXCursor_ObjCProtocolDecl { + interface.is_protocol = true; + } + + cursor.visit(|c| { + match c.kind() { + CXCursor_ObjCClassRef => { + if cursor.kind() == CXCursor_ObjCCategoryDecl { + // We are actually a category extension, and we found the reference + // to the original interface, so name this interface appropriately + interface.name = c.spelling(); + interface.category = Some(cursor.spelling()); + } + } + CXCursor_ObjCProtocolRef => { + // Gather protocols this interface conforms to + let needle = format!("P{}", c.spelling()); + let items_map = ctx.items(); + debug!( + "Interface {} conforms to {needle}, find the item", + interface.name, + ); + + for (id, item) in items_map { + if let Some(ty) = item.as_type() { + if let TypeKind::ObjCInterface(ref protocol) = + *ty.kind() + { + if protocol.is_protocol { + debug!( + "Checking protocol {}, ty.name {:?}", + protocol.name, + ty.name() + ); + if Some(needle.as_ref()) == ty.name() { + debug!("Found conforming protocol {item:?}"); + interface.conforms_to.push(id); + break; + } + } + } + } + } + } + CXCursor_ObjCInstanceMethodDecl | + CXCursor_ObjCClassMethodDecl => { + let name = c.spelling(); + let signature = + FunctionSig::from_ty(&c.cur_type(), &c, ctx) + .expect("Invalid function sig"); + let is_class_method = + c.kind() == CXCursor_ObjCClassMethodDecl; + let method = + ObjCMethod::new(&name, signature, is_class_method); + interface.add_method(method); + } + CXCursor_TemplateTypeParameter => { + let name = c.spelling(); + interface.template_names.push(name); + } + CXCursor_ObjCSuperClassRef => { + let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx); + interface.parent_class = Some(item.into()); + } + _ => {} + } + CXChildVisit_Continue + }); + Some(interface) + } + + fn add_method(&mut self, method: ObjCMethod) { + if method.is_class_method { + self.class_methods.push(method); + } else { + self.methods.push(method); + } + } +} + +impl ObjCMethod { + fn new( + name: &str, + signature: FunctionSig, + is_class_method: bool, + ) -> ObjCMethod { + let split_name: Vec<&str> = name.split(':').collect(); + + let rust_name = split_name.join("_"); + + ObjCMethod { + name: name.to_owned(), + rust_name, + signature, + is_class_method, + } + } + + /// Method name as converted to rust + /// like, `dataWithBytes_length`_ + pub(crate) fn rust_name(&self) -> &str { + self.rust_name.as_ref() + } + + /// Returns the methods signature as `FunctionSig` + pub(crate) fn signature(&self) -> &FunctionSig { + &self.signature + } + + /// Is this a class method? + pub(crate) fn is_class_method(&self) -> bool { + self.is_class_method + } + + /// Formats the method call + pub(crate) fn format_method_call( + &self, + args: &[TokenStream], + ) -> TokenStream { + let split_name: Vec> = self + .name + .split(':') + .enumerate() + .map(|(idx, name)| { + if name.is_empty() { + None + } else if idx == 0 { + // Try to parse the method name as an identifier. Having a keyword is ok + // 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())) + } else { + Some(Ident::new(name, Span::call_site())) + } + } else { + // Try to parse the current joining name as an identifier. This might fail if the name + // is a keyword, so we try to "r#" to it and parse again, this could also fail + // if the name is `crate`, `self`, `super` or `Self`, so we try to add the `_` + // suffix to it and parse again. If this also fails, we panic with the first + // error. + Some( + syn::parse_str::(name) + .or_else(|err| { + syn::parse_str::(&format!("r#{name}")) + .map_err(|_| err) + }) + .or_else(|err| { + syn::parse_str::(&format!("{name}_")) + .map_err(|_| err) + }) + .expect("Invalid identifier"), + ) + } + }) + .collect(); + + // No arguments + if args.is_empty() && split_name.len() == 1 { + let name = &split_name[0]; + return quote! { + #name + }; + } + + // Check right amount of arguments + 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 { + 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())); + } + + let args = split_name.into_iter().zip(args_without_types).map( + |(arg, arg_val)| { + if let Some(arg) = arg { + quote! { #arg: #arg_val } + } else { + quote! { #arg_val: #arg_val } + } + }, + ); + + quote! { + #( #args )* + } + } +} + +impl Trace for ObjCInterface { + type Extra = (); + + fn trace(&self, context: &BindgenContext, tracer: &mut T, _: &()) + where + T: Tracer, + { + for method in &self.methods { + method.signature.trace(context, tracer, &()); + } + + for class_method in &self.class_methods { + class_method.signature.trace(context, tracer, &()); + } + + for protocol in &self.conforms_to { + tracer.visit(*protocol); + } + } +} diff --git a/bindgen/ir/template.rs b/bindgen/ir/template.rs new file mode 100644 index 0000000000..7f3667879d --- /dev/null +++ b/bindgen/ir/template.rs @@ -0,0 +1,335 @@ +//! Template declaration and instantiation related things. +//! +//! The nomenclature surrounding templates is often confusing, so here are a few +//! brief definitions: +//! +//! * "Template definition": a class/struct/alias/function definition that takes +//! generic template parameters. For example: +//! +//! ```c++ +//! template +//! class List { +//! // ... +//! }; +//! ``` +//! +//! * "Template instantiation": an instantiation is a use of a template with +//! concrete template arguments. For example, `List`. +//! +//! * "Template specialization": an alternative template definition providing a +//! custom definition for instantiations with the matching template +//! arguments. This C++ feature is unsupported by bindgen. For example: +//! +//! ```c++ +//! template<> +//! class List { +//! // Special layout for int lists... +//! }; +//! ``` + +use super::context::{BindgenContext, ItemId, TypeId}; +use super::item::{IsOpaque, Item, ItemAncestors}; +use super::traversal::{EdgeKind, Trace, Tracer}; +use crate::clang; + +/// Template declaration (and such declaration's template parameters) related +/// methods. +/// +/// This trait's methods distinguish between `None` and `Some([])` for +/// declarations that are not templates and template declarations with zero +/// parameters, in general. +/// +/// Consider this example: +/// +/// ```c++ +/// template +/// class Foo { +/// T use_of_t; +/// U use_of_u; +/// +/// template +/// using Bar = V*; +/// +/// class Inner { +/// T x; +/// U y; +/// Bar z; +/// }; +/// +/// template +/// class Lol { +/// // No use of W, but here's a use of T. +/// T t; +/// }; +/// +/// template +/// class Wtf { +/// // X is not used because W is not used. +/// Lol lololol; +/// }; +/// }; +/// +/// class Qux { +/// int y; +/// }; +/// ``` +/// +/// 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. | 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. + /// + /// Note that these might *not* all be named types: C++ allows + /// constant-value template parameters as well as template-template + /// parameters. Of course, Rust does not allow generic parameters to be + /// anything but types, so we must treat them as opaque, and avoid + /// instantiating them. + fn self_template_params(&self, ctx: &BindgenContext) -> Vec; + + /// Get the number of free template parameters this template declaration + /// has. + fn num_self_template_params(&self, ctx: &BindgenContext) -> usize { + self.self_template_params(ctx).len() + } + + /// Get the complete set of template parameters that can affect this + /// declaration. + /// + /// Note that this item doesn't need to be a template declaration itself for + /// `Some` to be returned here (in contrast to `self_template_params`). If + /// this item is a member of a template declaration, then the parent's + /// template parameters are included here. + /// + /// In the example above, `Inner` depends on both of the `T` and `U` type + /// parameters, even though it is not itself a template declaration and + /// therefore has no type parameters itself. Perhaps it helps to think about + /// how we would fully reference such a member type in C++: + /// `Foo::Inner`. `Foo` *must* be instantiated with template + /// arguments before we can gain access to the `Inner` member type. + fn all_template_params(&self, ctx: &BindgenContext) -> Vec + where + Self: ItemAncestors, + { + let mut ancestors: Vec<_> = self.ancestors(ctx).collect(); + ancestors.reverse(); + ancestors + .into_iter() + .flat_map(|id| id.self_template_params(ctx).into_iter()) + .collect() + } + + /// Get only the set of template parameters that this item uses. This is a + /// subset of `all_template_params` and does not necessarily contain any of + /// `self_template_params`. + fn used_template_params(&self, ctx: &BindgenContext) -> Vec + where + Self: AsRef, + { + assert!( + ctx.in_codegen_phase(), + "template parameter usage is not computed until codegen" + ); + + let id = *self.as_ref(); + ctx.resolve_item(id) + .all_template_params(ctx) + .into_iter() + .filter(|p| ctx.uses_template_parameter(id, *p)) + .collect() + } +} + +/// A trait for things which may or may not be a named template type parameter. +pub(crate) trait AsTemplateParam { + /// Any extra information the implementor might need to make this decision. + type Extra; + + /// Convert this thing to the item ID of a named template type parameter. + fn as_template_param( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> Option; + + /// Is this a named template type parameter? + fn is_template_param( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> bool { + self.as_template_param(ctx, extra).is_some() + } +} + +/// A concrete instantiation of a generic template. +#[derive(Clone, Debug)] +pub(crate) struct TemplateInstantiation { + /// The template definition which this is instantiating. + definition: TypeId, + /// The concrete template arguments, which will be substituted in the + /// definition for the generic template parameters. + args: Vec, +} + +impl TemplateInstantiation { + /// Construct a new template instantiation from the given parts. + pub(crate) fn new(definition: TypeId, args: I) -> TemplateInstantiation + where + I: IntoIterator, + { + TemplateInstantiation { + definition, + args: args.into_iter().collect(), + } + } + + /// Get the template definition for this instantiation. + pub(crate) fn template_definition(&self) -> TypeId { + self.definition + } + + /// Get the concrete template arguments used in this instantiation. + pub(crate) fn template_arguments(&self) -> &[TypeId] { + &self.args[..] + } + + /// Parse a `TemplateInstantiation` from a clang `Type`. + pub(crate) fn from_ty( + ty: &clang::Type, + ctx: &mut BindgenContext, + ) -> Option { + use clang_sys::*; + + let template_args = ty.template_args().map_or(vec![], |args| match ty + .canonical_type() + .template_args() + { + Some(canonical_args) => { + let arg_count = args.len(); + args.chain(canonical_args.skip(arg_count)) + .filter(|t| t.kind() != CXType_Invalid) + .map(|t| { + Item::from_ty_or_ref(t, t.declaration(), None, ctx) + }) + .collect() + } + None => args + .filter(|t| t.kind() != CXType_Invalid) + .map(|t| Item::from_ty_or_ref(t, t.declaration(), None, ctx)) + .collect(), + }); + + let declaration = ty.declaration(); + let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl + { + Some(declaration) + } else { + declaration.specialized().or_else(|| { + let mut template_ref = None; + ty.declaration().visit(|child| { + if child.kind() == CXCursor_TemplateRef { + template_ref = Some(child); + return CXVisit_Break; + } + + // Instantiations of template aliases might have the + // TemplateRef to the template alias definition arbitrarily + // deep, so we need to recurse here and not only visit + // direct children. + CXChildVisit_Recurse + }); + + template_ref.and_then(|cur| cur.referenced()) + }) + }; + + let Some(definition) = definition else { + if !ty.declaration().is_builtin() { + warn!( + "Could not find template definition for template \ + instantiation" + ); + } + return None; + }; + + let template_definition = + Item::from_ty_or_ref(definition.cur_type(), definition, None, ctx); + + Some(TemplateInstantiation::new( + template_definition, + template_args, + )) + } +} + +impl IsOpaque for TemplateInstantiation { + type Extra = Item; + + /// Is this an opaque template instantiation? + fn is_opaque(&self, ctx: &BindgenContext, item: &Item) -> bool { + if self.template_definition().is_opaque(ctx, &()) { + return true; + } + + // TODO(#774): This doesn't properly handle opaque instantiations where + // an argument is itself an instantiation because `canonical_name` does + // not insert the template arguments into the name, ie it for nested + // template arguments it creates "Foo" instead of "Foo". The fully + // correct fix is to make `canonical_{name,path}` include template + // arguments properly. + + let mut path = item.path_for_allowlisting(ctx).clone(); + let args: Vec<_> = self + .template_arguments() + .iter() + .map(|arg| { + let arg_path = + ctx.resolve_item(*arg).path_for_allowlisting(ctx); + arg_path[1..].join("::") + }) + .collect(); + { + let last = path.last_mut().unwrap(); + last.push('<'); + last.push_str(&args.join(", ")); + last.push('>'); + } + + ctx.opaque_by_name(&path) + } +} + +impl Trace for TemplateInstantiation { + type Extra = (); + + fn trace(&self, _ctx: &BindgenContext, tracer: &mut T, _: &()) + where + T: Tracer, + { + tracer + .visit_kind(self.definition.into(), EdgeKind::TemplateDeclaration); + for arg in self.template_arguments() { + tracer.visit_kind(arg.into(), EdgeKind::TemplateArgument); + } + } +} diff --git a/src/ir/traversal.rs b/bindgen/ir/traversal.rs similarity index 85% rename from src/ir/traversal.rs rename to bindgen/ir/traversal.rs index 088e744a4b..01f3a8bd50 100644 --- a/src/ir/traversal.rs +++ b/bindgen/ir/traversal.rs @@ -12,14 +12,14 @@ use std::collections::{BTreeMap, VecDeque}; /// The `from` is left implicit: it is the concrete `Trace` implementer which /// yielded this outgoing edge. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Edge { +pub(crate) struct Edge { to: ItemId, kind: EdgeKind, } impl Edge { /// Construct a new edge whose referent is `to` and is of the given `kind`. - pub fn new(to: ItemId, kind: EdgeKind) -> Edge { + pub(crate) fn new(to: ItemId, kind: EdgeKind) -> Edge { Edge { to, kind } } } @@ -33,7 +33,7 @@ impl From for ItemId { /// The kind of edge reference. This is useful when we wish to only consider /// certain kinds of edges for a particular traversal or analysis. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum EdgeKind { +pub(crate) enum EdgeKind { /// A generic, catch-all edge. Generic, @@ -179,22 +179,16 @@ pub enum EdgeKind { /// A predicate to allow visiting only sub-sets of the whole IR graph by /// excluding certain edges from being followed by the traversal. -pub trait TraversalPredicate { - /// Should the traversal follow this edge, and visit everything that is - /// reachable through it? - fn should_follow(&self, ctx: &BindgenContext, edge: Edge) -> bool; -} - -impl TraversalPredicate for for<'a> fn(&'a BindgenContext, Edge) -> bool { - fn should_follow(&self, ctx: &BindgenContext, edge: Edge) -> bool { - (*self)(ctx, edge) - } -} +/// +/// The predicate must return true if the traversal should follow this edge +/// and visit everything that is reachable through it. +pub(crate) type TraversalPredicate = + for<'a> fn(&'a BindgenContext, Edge) -> bool; /// A `TraversalPredicate` implementation that follows all edges, and therefore /// traversals using this predicate will see the whole IR graph reachable from /// the traversal's roots. -pub fn all_edges(_: &BindgenContext, _: Edge) -> bool { +pub(crate) fn all_edges(_: &BindgenContext, _: Edge) -> bool { true } @@ -203,14 +197,14 @@ pub fn all_edges(_: &BindgenContext, _: Edge) -> bool { /// will only visit the traversal's roots and their inner types. This is used /// in no-recursive-allowlist mode, where inner types such as anonymous /// structs/unions still need to be processed. -pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool { +pub(crate) fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool { edge.kind == EdgeKind::InnerType } /// A `TraversalPredicate` implementation that only follows edges to items that /// are enabled for code generation. This lets us skip considering items for /// which are not reachable from code generation. -pub fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool { +pub(crate) fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool { let cc = &ctx.options().codegen_config; match edge.kind { EdgeKind::Generic => { @@ -240,8 +234,8 @@ pub fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool { /// The storage for the set of items that have been seen (although their /// outgoing edges might not have been fully traversed yet) in an active /// traversal. -pub trait TraversalStorage<'ctx> { - /// Construct a new instance of this TraversalStorage, for a new traversal. +pub(crate) trait TraversalStorage<'ctx> { + /// 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 @@ -266,7 +260,7 @@ impl<'ctx> TraversalStorage<'ctx> for ItemSet { /// each item. This is useful for providing debug assertions with meaningful /// diagnostic messages about dangling items. #[derive(Debug)] -pub struct Paths<'ctx>(BTreeMap, &'ctx BindgenContext); +pub(crate) struct Paths<'ctx>(BTreeMap, &'ctx BindgenContext); impl<'ctx> TraversalStorage<'ctx> for Paths<'ctx> { fn new(ctx: &'ctx BindgenContext) -> Self { @@ -293,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:?}" ); } @@ -307,7 +300,7 @@ impl<'ctx> TraversalStorage<'ctx> for Paths<'ctx> { /// Using a FIFO queue with a traversal will yield a breadth-first traversal, /// while using a LIFO queue will result in a depth-first traversal of the IR /// graph. -pub trait TraversalQueue: Default { +pub(crate) trait TraversalQueue: Default { /// Add a newly discovered item to the queue. fn push(&mut self, item: ItemId); @@ -336,7 +329,7 @@ impl TraversalQueue for VecDeque { } /// Something that can receive edges from a `Trace` implementation. -pub trait Tracer { +pub(crate) trait Tracer { /// Note an edge between items. Called from within a `Trace` implementation. fn visit_kind(&mut self, item: ItemId, kind: EdgeKind); @@ -351,14 +344,14 @@ where F: FnMut(ItemId, EdgeKind), { fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) { - (*self)(item, kind) + (*self)(item, kind); } } /// Trace all of the outgoing edges to other items. Implementations should call /// one of `tracer.visit(edge)` or `tracer.visit_kind(edge, EdgeKind::Whatever)` /// for each of their outgoing edges. -pub trait Trace { +pub(crate) trait Trace { /// If a particular type needs extra information beyond what it has in /// `self` and `context` to find its referenced items, its implementation /// can define this associated type, forcing callers to pass the needed @@ -378,11 +371,10 @@ pub trait Trace { /// An graph traversal of the transitive closure of references between items. /// /// See `BindgenContext::allowlisted_items` for more information. -pub struct ItemTraversal<'ctx, Storage, Queue, Predicate> +pub(crate) struct ItemTraversal<'ctx, Storage, Queue> where Storage: TraversalStorage<'ctx>, Queue: TraversalQueue, - Predicate: TraversalPredicate, { ctx: &'ctx BindgenContext, @@ -393,25 +385,23 @@ where queue: Queue, /// The predicate that determines which edges this traversal will follow. - predicate: Predicate, + predicate: TraversalPredicate, /// The item we are currently traversing. currently_traversing: Option, } -impl<'ctx, Storage, Queue, Predicate> - ItemTraversal<'ctx, Storage, Queue, Predicate> +impl<'ctx, Storage, Queue> ItemTraversal<'ctx, Storage, Queue> where Storage: TraversalStorage<'ctx>, Queue: TraversalQueue, - Predicate: TraversalPredicate, { /// Begin a new traversal, starting from the given roots. - pub fn new( + pub(crate) fn new( ctx: &'ctx BindgenContext, roots: R, - predicate: Predicate, - ) -> ItemTraversal<'ctx, Storage, Queue, Predicate> + predicate: TraversalPredicate, + ) -> ItemTraversal<'ctx, Storage, Queue> where R: IntoIterator, { @@ -433,33 +423,29 @@ where } } -impl<'ctx, Storage, Queue, Predicate> Tracer - for ItemTraversal<'ctx, Storage, Queue, Predicate> +impl<'ctx, Storage, Queue> Tracer for ItemTraversal<'ctx, Storage, Queue> where Storage: TraversalStorage<'ctx>, Queue: TraversalQueue, - Predicate: TraversalPredicate, { fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) { let edge = Edge::new(item, kind); - if !self.predicate.should_follow(self.ctx, edge) { + if !(self.predicate)(self.ctx, edge) { return; } let is_newly_discovered = self.seen.add(self.currently_traversing, item); if is_newly_discovered { - self.queue.push(item) + self.queue.push(item); } } } -impl<'ctx, Storage, Queue, Predicate> Iterator - for ItemTraversal<'ctx, Storage, Queue, Predicate> +impl<'ctx, Storage, Queue> Iterator for ItemTraversal<'ctx, Storage, Queue> where Storage: TraversalStorage<'ctx>, Queue: TraversalQueue, - Predicate: TraversalPredicate, { type Item = ItemId; @@ -488,21 +474,5 @@ where /// /// See `BindgenContext::assert_no_dangling_item_traversal` for more /// information. -pub type AssertNoDanglingItemsTraversal<'ctx> = ItemTraversal< - 'ctx, - Paths<'ctx>, - VecDeque, - for<'a> fn(&'a BindgenContext, Edge) -> bool, ->; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[allow(dead_code)] - fn traversal_predicate_is_object_safe() { - // This should compile only if TraversalPredicate is object safe. - fn takes_by_trait_object(_: &dyn TraversalPredicate) {} - } -} +pub(crate) type AssertNoDanglingItemsTraversal<'ctx> = + ItemTraversal<'ctx, Paths<'ctx>, VecDeque>; diff --git a/src/ir/ty.rs b/bindgen/ir/ty.rs similarity index 81% rename from src/ir/ty.rs rename to bindgen/ir/ty.rs index d573408c3b..a53de31c6a 100644 --- a/src/ir/ty.rs +++ b/bindgen/ir/ty.rs @@ -5,26 +5,27 @@ use super::context::{BindgenContext, ItemId, TypeId}; use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; -use super::int::IntKind; use super::item::{IsOpaque, Item}; -use super::layout::{Layout, Opaque}; +use super::layout::Layout; use super::objc::ObjCInterface; use super::template::{ AsTemplateParam, TemplateInstantiation, TemplateParameters, }; use super::traversal::{EdgeKind, Trace, Tracer}; use crate::clang::{self, Cursor}; -use crate::parse::{ClangItemParser, ParseError, ParseResult}; +use crate::parse::{ParseError, ParseResult}; use std::borrow::Cow; use std::io; +pub use super::int::IntKind; + /// The base representation of a type in bindgen. /// /// A type has an optional name, which if present cannot be empty, a `layout` /// (size, alignment and packedness) if known, a `Kind`, which determines which /// kind of type it is, and whether the type is const. #[derive(Debug)] -pub struct Type { +pub(crate) struct Type { /// The name of the type, or None if it was an unnamed struct or union. name: Option, /// The layout of the type, if known. @@ -39,21 +40,12 @@ pub struct Type { /// traits, and so if we have a type containing an array with more than this /// many items, we won't be able to derive common traits on that type. /// -pub const RUST_DERIVE_IN_ARRAY_LIMIT: usize = 32; +pub(crate) const RUST_DERIVE_IN_ARRAY_LIMIT: usize = 32; impl Type { - /// Get the underlying `CompInfo` for this type, or `None` if this is some - /// other kind of type. - pub fn as_comp(&self) -> Option<&CompInfo> { - match self.kind { - TypeKind::Comp(ref ci) => Some(ci), - _ => None, - } - } - /// Get the underlying `CompInfo` for this type as a mutable reference, or /// `None` if this is some other kind of type. - pub fn as_comp_mut(&mut self) -> Option<&mut CompInfo> { + pub(crate) fn as_comp_mut(&mut self) -> Option<&mut CompInfo> { match self.kind { TypeKind::Comp(ref mut ci) => Some(ci), _ => None, @@ -61,7 +53,7 @@ impl Type { } /// Construct a new `Type`. - pub fn new( + pub(crate) fn new( name: Option, layout: Option, kind: TypeKind, @@ -75,33 +67,49 @@ 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 fn kind(&self) -> &TypeKind { + pub(crate) fn kind(&self) -> &TypeKind { &self.kind } /// Get a mutable reference to this type's kind. - pub fn kind_mut(&mut self) -> &mut TypeKind { + pub(crate) fn kind_mut(&mut self) -> &mut TypeKind { &mut self.kind } /// Get this type's name. - pub fn name(&self) -> Option<&str> { + pub(crate) fn name(&self) -> Option<&str> { self.name.as_deref() } /// Whether this is a block pointer type. - pub fn is_block_pointer(&self) -> bool { + pub(crate) fn is_block_pointer(&self) -> bool { matches!(self.kind, TypeKind::BlockPointer(..)) } + /// Is this an integer type, including `bool` or `char`? + pub(crate) fn is_int(&self) -> bool { + matches!(self.kind, TypeKind::Int(_)) + } + /// Is this a compound type? - pub fn is_comp(&self) -> bool { + pub(crate) fn is_comp(&self) -> bool { matches!(self.kind, TypeKind::Comp(..)) } /// Is this a union? - pub fn is_union(&self) -> bool { + pub(crate) fn is_union(&self) -> bool { match self.kind { TypeKind::Comp(ref comp) => comp.is_union(), _ => false, @@ -109,32 +117,31 @@ impl Type { } /// Is this type of kind `TypeKind::TypeParam`? - pub fn is_type_param(&self) -> bool { + pub(crate) fn is_type_param(&self) -> bool { matches!(self.kind, TypeKind::TypeParam) } /// Is this a template instantiation type? - pub fn is_template_instantiation(&self) -> bool { + pub(crate) fn is_template_instantiation(&self) -> bool { matches!(self.kind, TypeKind::TemplateInstantiation(..)) } - /// Is this a template alias type? - pub fn is_template_alias(&self) -> bool { - matches!(self.kind, TypeKind::TemplateAlias(..)) - } - /// Is this a function type? - pub fn is_function(&self) -> bool { + pub(crate) fn is_function(&self) -> bool { matches!(self.kind, TypeKind::Function(..)) } /// Is this an enum type? - pub fn is_enum(&self) -> bool { + pub(crate) fn is_enum(&self) -> bool { matches!(self.kind, TypeKind::Enum(..)) } + /// Is this void? + pub(crate) fn is_void(&self) -> bool { + matches!(self.kind, TypeKind::Void) + } /// Is this either a builtin or named type? - pub fn is_builtin_or_type_param(&self) -> bool { + pub(crate) fn is_builtin_or_type_param(&self) -> bool { matches!( self.kind, TypeKind::Void | @@ -150,29 +157,29 @@ impl Type { } /// Creates a new named type, with name `name`. - pub fn named(name: String) -> Self { + pub(crate) fn named(name: String) -> Self { let name = if name.is_empty() { None } else { Some(name) }; Self::new(name, None, TypeKind::TypeParam, false) } /// Is this a floating point type? - pub fn is_float(&self) -> bool { + pub(crate) fn is_float(&self) -> bool { matches!(self.kind, TypeKind::Float(..)) } /// Is this a boolean type? - pub fn is_bool(&self) -> bool { + pub(crate) fn is_bool(&self) -> bool { matches!(self.kind, TypeKind::Int(IntKind::Bool)) } /// Is this an integer type? - pub fn is_integer(&self) -> bool { + pub(crate) fn is_integer(&self) -> bool { matches!(self.kind, TypeKind::Int(..)) } /// Cast this type to an integer kind, or `None` if it is not an integer /// type. - pub fn as_integer(&self) -> Option { + pub(crate) fn as_integer(&self) -> Option { match self.kind { TypeKind::Int(int_kind) => Some(int_kind), _ => None, @@ -180,25 +187,20 @@ impl Type { } /// Is this a `const` qualified type? - pub fn is_const(&self) -> bool { + pub(crate) fn is_const(&self) -> bool { self.is_const } - /// Is this a reference to another type? - pub fn is_type_ref(&self) -> bool { - matches!( - self.kind, - TypeKind::ResolvedTypeRef(_) | TypeKind::UnresolvedTypeRef(_, _, _) - ) - } - /// Is this an unresolved reference? - pub fn is_unresolved_ref(&self) -> bool { + pub(crate) fn is_unresolved_ref(&self) -> bool { matches!(self.kind, TypeKind::UnresolvedTypeRef(_, _, _)) } /// Is this a incomplete array type? - pub fn is_incomplete_array(&self, ctx: &BindgenContext) -> Option { + pub(crate) fn is_incomplete_array( + &self, + ctx: &BindgenContext, + ) -> Option { match self.kind { TypeKind::Array(item, len) => { if len == 0 { @@ -215,13 +217,14 @@ impl Type { } /// What is the layout of this type? - pub fn layout(&self, ctx: &BindgenContext) -> Option { + pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option { self.layout.or_else(|| { match self.kind { TypeKind::Comp(ref ci) => ci.layout(ctx), - TypeKind::Array(inner, length) if length == 0 => Some( - Layout::new(0, ctx.resolve_type(inner).layout(ctx)?.align), - ), + TypeKind::Array(inner, 0) => Some(Layout::new( + 0, + ctx.resolve_type(inner).layout(ctx)?.align, + )), // FIXME(emilio): This is a hack for anonymous union templates. // Use the actual pointer size! TypeKind::Pointer(..) => Some(Layout::new( @@ -240,7 +243,7 @@ impl Type { /// avoid generating invalid code with some cases we can't handle, see: /// /// tests/headers/381-decltype-alias.hpp - pub fn is_invalid_type_param(&self) -> bool { + pub(crate) fn is_invalid_type_param(&self) -> bool { match self.kind { TypeKind::TypeParam => { let name = self.name().expect("Unnamed named type?"); @@ -251,17 +254,17 @@ 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) } - /// Get this type's santizied name. - pub fn sanitized_name<'a>( + /// Get this type's sanitized name. + pub(crate) fn sanitized_name<'a>( &'a self, ctx: &BindgenContext, ) -> Option> { @@ -269,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, }; @@ -277,14 +280,14 @@ 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. - pub fn canonical_type<'tr>( + /// See [`Self::safe_canonical_type`]. + pub(crate) fn canonical_type<'tr>( &'tr self, ctx: &'tr BindgenContext, ) -> &'tr Type { @@ -297,7 +300,7 @@ impl Type { /// For example, for a `typedef`, the canonical type would be the /// `typedef`ed type, for a template instantiation, would be the template /// its specializing, and so on. Return None if the type is unresolved. - pub fn safe_canonical_type<'tr>( + pub(crate) fn safe_canonical_type<'tr>( &'tr self, ctx: &'tr BindgenContext, ) -> Option<&'tr Type> { @@ -336,7 +339,7 @@ impl Type { /// There are some types we don't want to stop at when finding an opaque /// item, so we can arrive to the proper item that needs to be generated. - pub fn should_be_traced_unconditionally(&self) -> bool { + pub(crate) fn should_be_traced_unconditionally(&self) -> bool { matches!( self.kind, TypeKind::Comp(..) | @@ -479,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] @@ -490,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_remaing() { +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 { @@ -564,8 +567,10 @@ impl TemplateParameters for TypeKind { } /// The kind of float this type represents. -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum FloatKind { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum FloatKind { + /// A half (`_Float16` or `__fp16`) + Float16, /// A `float`. Float, /// A `double`. @@ -578,7 +583,7 @@ pub enum FloatKind { /// The different kinds of types that we can parse. #[derive(Debug)] -pub enum TypeKind { +pub(crate) enum TypeKind { /// The void type. Void, @@ -588,7 +593,7 @@ pub 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, @@ -629,7 +634,7 @@ pub 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 @@ -640,15 +645,10 @@ pub 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. /// @@ -675,7 +675,7 @@ impl Type { /// /// It's sort of nasty and full of special-casing, but hopefully the /// comments in every special case justify why they're there. - pub fn from_clang_ty( + pub(crate) fn from_clang_ty( potential_id: ItemId, ty: &clang::Type, location: Cursor, @@ -691,18 +691,22 @@ 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())); } } let layout = ty.fallible_layout(ctx).ok(); let cursor = ty.declaration(); - let mut name = cursor.spelling(); + let is_anonymous = cursor.is_anonymous(); + let mut name = if is_anonymous { + None + } else { + Some(cursor.spelling()).filter(|n| !n.is_empty()) + }; 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()); @@ -712,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; } _ => {} } @@ -720,7 +724,7 @@ impl Type { // Objective C template type parameter // FIXME: This is probably wrong, we are attempting to find the // objc template params, which seem to manifest as a typedef. - // We are rewriting them as id to suppress multiple conflicting + // We are rewriting them as ID to suppress multiple conflicting // typedefs at root level if ty_kind == CXType_Typedef { let is_template_type_param = @@ -732,7 +736,7 @@ impl Type { if is_canonical_objcpointer && is_template_type_param { // Objective-C generics are just ids with fancy name. // To keep it simple, just name them ids - name = "id".to_owned(); + name = Some("id".to_owned()); } } @@ -744,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, )); } @@ -777,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, @@ -798,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, @@ -861,7 +862,7 @@ impl Type { return Err(ParseError::Recurse); } } else { - name = location.spelling(); + name = Some(location.spelling()); } let complex = CompInfo::from_ty( @@ -870,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 => { @@ -903,7 +901,7 @@ impl Type { CXType_Typedef ); - name = current.spelling(); + name = Some(location.spelling()); let inner_ty = cur .typedef_type() @@ -931,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) @@ -949,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, @@ -970,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, @@ -992,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); } } @@ -1009,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); } @@ -1031,7 +1010,16 @@ impl Type { CXType_ObjCObjectPointer | CXType_MemberPointer | CXType_Pointer => { - let pointee = ty.pointee_type().unwrap(); + let mut pointee = ty.pointee_type().unwrap(); + if *ty != canonical_ty { + let canonical_pointee = + canonical_ty.pointee_type().unwrap(); + // clang sometimes loses pointee constness here, see + // #2244. + if canonical_pointee.is_const() != pointee.is_const() { + pointee = canonical_pointee; + } + } let inner = Item::from_ty_or_ref(pointee, location, None, ctx); TypeKind::Pointer(inner) @@ -1080,26 +1068,41 @@ impl Type { } CXType_Typedef => { let inner = cursor.typedef_type().expect("Not valid Type?"); - let inner = + let inner_id = Item::from_ty_or_ref(inner, location, None, ctx); - if inner == potential_id { + if inner_id == potential_id { warn!( - "Generating oqaque type instead of self-referential \ + "Generating opaque type instead of self-referential \ typedef"); // This can happen if we bail out of recursive situations // within the clang parsing. TypeKind::Opaque } else { - TypeKind::Alias(inner) + // Check if this type definition is an alias to a pointer of a `struct` / + // `union` / `enum` with the same name and add the `_ptr` suffix to it to + // avoid name collisions. + if let Some(ref mut name) = name { + if inner.kind() == CXType_Pointer && + !ctx.options().c_naming + { + let pointee = inner.pointee_type().unwrap(); + if pointee.kind() == CXType_Elaborated && + pointee.declaration().spelling() == *name + { + *name += "_ptr"; + } + } + } + TypeKind::Alias(inner_id) } } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); - if name.is_empty() { + if !is_anonymous { let pretty_name = ty.spelling(); if clang::is_valid_identifier(&pretty_name) { - name = pretty_name; + name = Some(pretty_name); } } @@ -1114,25 +1117,24 @@ impl Type { ) .expect("Not a complex type?"); - if name.is_empty() { + if !is_anonymous { // The pretty-printed name may contain typedefed name, // but may also be "struct (anonymous at .h:1)" let pretty_name = ty.spelling(); if clang::is_valid_identifier(&pretty_name) { - name = pretty_name; + name = Some(pretty_name); } } TypeKind::Comp(complex) } - CXType_Vector => { + CXType_Vector | CXType_ExtVector => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, None, ctx, - ) - .expect("Not able to resolve vector element?"); + )?; TypeKind::Vector(inner, ty.num_elements().unwrap()) } CXType_ConstantArray => { @@ -1145,6 +1147,18 @@ impl Type { .expect("Not able to resolve array element?"); TypeKind::Array(inner, ty.num_elements().unwrap()) } + CXType_Atomic => { + // TODO(emilio): Maybe we can preserve the "is atomic" bit somehow and generate + // something more useful... But for now this is better than panicking or + // generating nothing. + return Self::from_clang_ty( + potential_id, + &ty.atomic_value_type(), + location, + parent_id, + ctx, + ); + } CXType_Elaborated => { return Self::from_clang_ty( potential_id, @@ -1159,7 +1173,9 @@ impl Type { CXType_ObjCClass | CXType_ObjCInterface => { let interface = ObjCInterface::from_ty(&location, ctx) .expect("Not a valid objc interface?"); - name = interface.rust_name(); + if !is_anonymous { + name = Some(interface.rust_name()); + } TypeKind::ObjCInterface(interface) } CXType_Dependent => { @@ -1167,22 +1183,19 @@ impl Type { } _ => { warn!( - "unsupported type: kind = {:?}; ty = {:?}; at {:?}", + "unsupported type: kind = {:?}; ty = {ty:?}; at {location:?}", ty.kind(), - ty, - location ); return Err(ParseError::Continue); } } }; - let name = if name.is_empty() { None } else { Some(name) }; + name = name.filter(|n| !n.is_empty()); 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()? @@ -1197,6 +1210,10 @@ impl Trace for Type { where T: Tracer, { + 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; + } match *self.kind() { TypeKind::Pointer(inner) | TypeKind::Reference(inner) | diff --git a/bindgen/ir/var.rs b/bindgen/ir/var.rs new file mode 100644 index 0000000000..9d72dcf06e --- /dev/null +++ b/bindgen/ir/var.rs @@ -0,0 +1,523 @@ +//! Intermediate representation of variables. + +use super::super::codegen::MacroTypeVariation; +use super::context::{BindgenContext, TypeId}; +use super::dot::DotAttributes; +use super::function::cursor_mangling; +use super::int::IntKind; +use super::item::Item; +use super::ty::{FloatKind, TypeKind}; +use crate::callbacks::{ItemInfo, ItemKind, MacroParsingBehavior}; +use crate::clang; +use crate::clang::ClangToken; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; + +use std::io; +use std::num::Wrapping; + +/// The type for a constant variable. +#[derive(Debug)] +pub(crate) enum VarType { + /// A boolean. + Bool(bool), + /// An integer. + Int(i64), + /// A floating point number. + Float(f64), + /// A character. + Char(u8), + /// A string, not necessarily well-formed utf-8. + String(Vec), +} + +/// A `Var` is our intermediate representation of a variable. +#[derive(Debug)] +pub(crate) struct Var { + /// The name of the variable. + name: String, + /// The mangled name of the variable. + mangled_name: Option, + /// The link name of the variable. + link_name: Option, + /// The type of the variable. + ty: TypeId, + /// The value of the variable, that needs to be suitable for `ty`. + val: Option, + /// Whether this variable is const. + is_const: bool, +} + +impl Var { + /// Construct a new `Var`. + pub(crate) fn new( + name: String, + mangled_name: Option, + link_name: Option, + ty: TypeId, + val: Option, + is_const: bool, + ) -> Var { + assert!(!name.is_empty()); + Var { + name, + mangled_name, + link_name, + ty, + val, + is_const, + } + } + + /// Is this variable `const` qualified? + pub(crate) fn is_const(&self) -> bool { + self.is_const + } + + /// The value of this constant variable, if any. + pub(crate) fn val(&self) -> Option<&VarType> { + self.val.as_ref() + } + + /// Get this variable's type. + pub(crate) fn ty(&self) -> TypeId { + self.ty + } + + /// Get this variable's name. + pub(crate) fn name(&self) -> &str { + &self.name + } + + /// Get this variable's mangled name. + pub(crate) fn mangled_name(&self) -> Option<&str> { + self.mangled_name.as_deref() + } + + /// Get this variable's link name. + pub fn link_name(&self) -> Option<&str> { + self.link_name.as_deref() + } +} + +impl DotAttributes for Var { + fn dot_attributes( + &self, + _ctx: &BindgenContext, + out: &mut W, + ) -> io::Result<()> + where + W: io::Write, + { + if self.is_const { + writeln!(out, "consttrue")?; + } + + if let Some(ref mangled) = self.mangled_name { + writeln!(out, "mangled name{mangled}")?; + } + + Ok(()) + } +} + +fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { + if value < 0 || + ctx.options().default_macro_constant_type == + MacroTypeVariation::Signed + { + if value < i64::from(i32::MIN) || value > i64::from(i32::MAX) { + IntKind::I64 + } else if !ctx.options().fit_macro_constants || + value < i64::from(i16::MIN) || + value > i64::from(i16::MAX) + { + IntKind::I32 + } else if value < i64::from(i8::MIN) || value > i64::from(i8::MAX) { + IntKind::I16 + } else { + IntKind::I8 + } + } else if value > i64::from(u32::MAX) { + IntKind::U64 + } else if !ctx.options().fit_macro_constants || value > i64::from(u16::MAX) + { + IntKind::U32 + } 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. +fn handle_function_macro( + cursor: &clang::Cursor, + callbacks: &dyn crate::callbacks::ParseCallbacks, +) { + let is_closing_paren = |t: &ClangToken| { + // Test cheap token kind before comparing exact spellings. + t.kind == clang_sys::CXToken_Punctuation && t.spelling() == b")" + }; + let tokens: Vec<_> = cursor.tokens().iter().collect(); + if let Some(boundary) = tokens.iter().position(is_closing_paren) { + let mut spelled = tokens.iter().map(ClangToken::spelling); + // Add 1, to convert index to length. + let left = spelled.by_ref().take(boundary + 1); + let left = left.collect::>().concat(); + if let Ok(left) = String::from_utf8(left) { + let right: Vec<_> = spelled.collect(); + callbacks.func_macro(&left, &right); + } + } +} + +impl ClangSubItemParser for Var { + fn parse( + cursor: clang::Cursor, + ctx: &mut BindgenContext, + ) -> Result, ParseError> { + use cexpr::expr::EvalResult; + use cexpr::literal::CChar; + use clang_sys::*; + match cursor.kind() { + CXCursor_MacroDefinition => { + for callbacks in &ctx.options().parse_callbacks { + match callbacks.will_parse_macro(&cursor.spelling()) { + MacroParsingBehavior::Ignore => { + return Err(ParseError::Continue); + } + MacroParsingBehavior::Default => {} + } + + if cursor.is_macro_function_like() { + handle_function_macro(&cursor, callbacks.as_ref()); + // We handled the macro, skip macro processing below. + return Err(ParseError::Continue); + } + } + + let value = parse_macro(ctx, &cursor); + + let Some((id, value)) = value else { + return Err(ParseError::Continue); + }; + + assert!(!id.is_empty(), "Empty macro name?"); + + let previously_defined = ctx.parsed_macro(&id); + + // NB: It's important to "note" the macro even if the result is + // not an integer, otherwise we might loose other kind of + // derived macros. + ctx.note_parsed_macro(id.clone(), value.clone()); + + if previously_defined { + let name = String::from_utf8(id).unwrap(); + duplicated_macro_diagnostic(&name, cursor.location(), ctx); + return Err(ParseError::Continue); + } + + // NOTE: Unwrapping, here and above, is safe, because the + // identifier of a token comes straight from clang, and we + // enforce utf8 there, so we should have already panicked at + // this point. + let name = String::from_utf8(id).unwrap(); + let (type_kind, val) = match value { + EvalResult::Invalid => return Err(ParseError::Continue), + EvalResult::Float(f) => { + (TypeKind::Float(FloatKind::Double), VarType::Float(f)) + } + EvalResult::Char(c) => { + let c = match c { + CChar::Char(c) => { + assert_eq!(c.len_utf8(), 1); + c as u8 + } + CChar::Raw(c) => u8::try_from(c).unwrap(), + }; + + (TypeKind::Int(IntKind::U8), VarType::Char(c)) + } + EvalResult::Str(val) => { + let char_ty = Item::builtin_type( + TypeKind::Int(IntKind::U8), + true, + ctx, + ); + for callbacks in &ctx.options().parse_callbacks { + callbacks.str_macro(&name, &val); + } + (TypeKind::Pointer(char_ty), VarType::String(val)) + } + EvalResult::Int(Wrapping(value)) => { + let kind = ctx + .options() + .last_callback(|c| c.int_macro(&name, value)) + .unwrap_or_else(|| { + default_macro_constant_type(ctx, value) + }); + + (TypeKind::Int(kind), VarType::Int(value)) + } + }; + + let ty = Item::builtin_type(type_kind, true, ctx); + + Ok(ParseResult::New( + Var::new(name, None, None, ty, Some(val), true), + Some(cursor), + )) + } + CXCursor_VarDecl => { + let mut name = cursor.spelling(); + if cursor.linkage() == CXLinkage_External { + if let Some(nm) = ctx.options().last_callback(|callbacks| { + callbacks.generated_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Var, + }) + }) { + name = nm; + } + } + // No more changes to name + let name = name; + + if name.is_empty() { + warn!("Empty constant name?"); + return Err(ParseError::Continue); + } + + let link_name = ctx.options().last_callback(|callbacks| { + callbacks.generated_link_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Var, + }) + }); + + let ty = cursor.cur_type(); + + // TODO(emilio): do we have to special-case constant arrays in + // some other places? + let is_const = ty.is_const() || + ([CXType_ConstantArray, CXType_IncompleteArray] + .contains(&ty.kind()) && + ty.elem_type() + .is_some_and(|element| element.is_const())); + + let ty = match Item::from_ty(&ty, cursor, None, ctx) { + Ok(ty) => ty, + Err(e) => { + assert!( + matches!(ty.kind(), CXType_Auto | CXType_Unexposed), + "Couldn't resolve constant type, and it \ + wasn't an nondeductible auto type or unexposed \ + type: {ty:?}" + ); + return Err(e); + } + }; + + // Note: Ty might not be totally resolved yet, see + // tests/headers/inner_const.hpp + // + // That's fine because in that case we know it's not a literal. + let canonical_ty = ctx + .safe_resolve_type(ty) + .and_then(|t| t.safe_canonical_type(ctx)); + + 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 TypeKind::Int(kind) = *canonical_ty.unwrap().kind() + else { + unreachable!() + }; + + let mut val = cursor.evaluate().and_then(|v| v.as_int()); + if val.is_none() { + val = get_integer_literal_from_cursor(&cursor); + } + + val.map(|val| { + if kind == IntKind::Bool { + VarType::Bool(val != 0) + } else { + VarType::Int(val) + } + }) + } else if is_float { + cursor + .evaluate() + .and_then(|v| v.as_double()) + .map(VarType::Float) + } else { + cursor + .evaluate() + .and_then(|v| v.as_literal_string()) + .map(VarType::String) + }; + + let mangling = cursor_mangling(ctx, &cursor); + let var = + Var::new(name, mangling, link_name, ty, value, is_const); + + Ok(ParseResult::New(var, Some(cursor))) + } + _ => { + /* TODO */ + Err(ParseError::Continue) + } + } + } +} + +/// This function uses a [`FallbackTranslationUnit`][clang::FallbackTranslationUnit] to parse each +/// macro that cannot be parsed by the normal bindgen process for `#define`s. +/// +/// To construct the [`FallbackTranslationUnit`][clang::FallbackTranslationUnit], first precompiled +/// headers are generated for all input headers. An empty temporary `.c` file is generated to pass +/// to the translation unit. On the evaluation of each macro, a [`String`] is generated with the +/// new contents of the empty file and passed in for reparsing. The precompiled headers and +/// preservation of the [`FallbackTranslationUnit`][clang::FallbackTranslationUnit] across macro +/// evaluations are both optimizations that have significantly improved the performance. +fn parse_macro_clang_fallback( + ctx: &mut BindgenContext, + cursor: &clang::Cursor, +) -> Option<(Vec, cexpr::expr::EvalResult)> { + if !ctx.options().clang_macro_fallback { + return None; + } + + let ftu = ctx.try_ensure_fallback_translation_unit()?; + 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(); + // Last child in root is function declaration + // Should be FunctionDecl + let main_func = root_children.last()?; + // Children should all be statements in function declaration + let all_stmts = main_func.collect_children(); + // First child in all_stmts should be the statement containing the macro to evaluate + // Should be CompoundStmt + let macro_stmt = all_stmts.first()?; + // Children should all be expressions from the compound statement + let paren_exprs = macro_stmt.collect_children(); + // First child in all_exprs is the expression utilizing the given macro to be evaluated + // Should be ParenExpr + let paren = paren_exprs.first()?; + + Some(( + cursor.spelling().into_bytes(), + cexpr::expr::EvalResult::Int(Wrapping(paren.evaluate()?.as_int()?)), + )) +} + +/// Try and parse a macro using all the macros parsed until now. +fn parse_macro( + ctx: &mut BindgenContext, + cursor: &clang::Cursor, +) -> Option<(Vec, cexpr::expr::EvalResult)> { + use cexpr::expr; + + 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()); + + match parser.macro_definition(&cexpr_tokens) { + Ok((_, (id, val))) => Some((id.into(), val)), + _ => parse_macro_clang_fallback(ctx, cursor), + } +} + +fn parse_int_literal_tokens(cursor: &clang::Cursor) -> Option { + use cexpr::expr; + use cexpr::expr::EvalResult; + + let cexpr_tokens = cursor.cexpr_tokens(); + + // TODO(emilio): We can try to parse other kinds of literals. + match expr::expr(&cexpr_tokens) { + Ok((_, EvalResult::Int(Wrapping(val)))) => Some(val), + _ => None, + } +} + +fn get_integer_literal_from_cursor(cursor: &clang::Cursor) -> Option { + use clang_sys::*; + let mut value = None; + cursor.visit(|c| { + match c.kind() { + CXCursor_IntegerLiteral | CXCursor_UnaryOperator => { + value = parse_int_literal_tokens(&c); + } + CXCursor_UnexposedExpr => { + value = get_integer_literal_from_cursor(&c); + } + _ => (), + } + if value.is_some() { + CXChildVisit_Break + } else { + CXChildVisit_Continue + } + }); + value +} + +fn duplicated_macro_diagnostic( + macro_name: &str, + _location: clang::SourceLocation, + _ctx: &BindgenContext, +) { + warn!("Duplicated macro definition: {macro_name}"); + + #[cfg(feature = "experimental")] + // FIXME (pvdrz & amanjeev): This diagnostic message shows way too often to be actually + // useful. We have to change the logic where this function is called to be able to emit this + // message only when the duplication is an actual issue. + // + // If I understood correctly, `bindgen` ignores all `#undef` directives. Meaning that this: + // ```c + // #define FOO 1 + // #undef FOO + // #define FOO 2 + // ``` + // + // Will trigger this message even though there's nothing wrong with it. + #[allow(clippy::overly_complex_bool_expr)] + if false && _ctx.options().emit_diagnostics { + use crate::diagnostics::{get_line, Diagnostic, Level, Slice}; + use std::borrow::Cow; + + let mut slice = Slice::default(); + let mut source = Cow::from(macro_name); + + let (file, line, col, _) = _location.location(); + if let Some(filename) = file.name() { + if let Ok(Some(code)) = get_line(&filename, line) { + source = code.into(); + } + slice.with_location(filename, line, col); + } + + slice.with_source(source); + + Diagnostic::default() + .with_title("Duplicated macro definition.", Level::Warning) + .add_slice(slice) + .add_annotation("This macro had a duplicate.", Level::Note) + .display(); + } +} diff --git a/bindgen/lib.rs b/bindgen/lib.rs new file mode 100644 index 0000000000..f2c8870e05 --- /dev/null +++ b/bindgen/lib.rs @@ -0,0 +1,1420 @@ +//! Generate Rust bindings for C and C++ libraries. +//! +//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++ +//! functions and use types defined in the header. +//! +//! See the [`Builder`](./struct.Builder.html) struct for usage. +//! +//! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for +//! additional documentation. +#![deny(missing_docs)] +#![deny(unused_extern_crates)] +#![deny(clippy::disallowed_methods)] +// To avoid rather annoying warnings when matching with CXCursor_xxx as a +// constant. +#![allow(non_upper_case_globals)] +// `quote!` nests quite deeply. +#![recursion_limit = "128"] + +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate quote; + +#[cfg(feature = "logging")] +#[macro_use] +extern crate log; + +#[cfg(not(feature = "logging"))] +#[macro_use] +mod log_stubs; + +#[macro_use] +mod extra_assertions; + +mod codegen; +mod deps; +mod options; +mod time; + +pub mod callbacks; + +mod clang; +#[cfg(feature = "experimental")] +mod diagnostics; +mod features; +mod ir; +mod parse; +mod regex_set; + +pub use codegen::{ + AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle, +}; +pub use features::{RustEdition, RustTarget, LATEST_STABLE_RUST}; +pub use ir::annotations::FieldVisibilityKind; +pub use ir::function::Abi; +#[cfg(feature = "__cli")] +pub use options::cli::builder_from_flags; + +use codegen::CodegenError; +use features::RustFeatures; +use ir::comment; +use ir::context::{BindgenContext, ItemId}; +use ir::item::Item; +use options::BindgenOptions; +use parse::ParseError; + +use std::borrow::Cow; +use std::collections::hash_map::Entry; +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; + +// Some convenient typedefs for a fast hash map and hash set. +type HashMap = rustc_hash::FxHashMap; +type HashSet = rustc_hash::FxHashSet; + +/// Default prefix for the anon fields. +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 { + 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 { + for w in clang_args.windows(2) { + if w[0].as_ref() == "-xc++" || w[1].as_ref() == "-xc++" { + return true; + } + if w[0].as_ref() == "-x" && w[1].as_ref() == "c++" { + return true; + } + if w[0].as_ref() == "-include" && file_is_cpp(w[1].as_ref()) { + return true; + } + } + false +} + +bitflags! { + /// A type used to indicate which kind of items we have to generate. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + pub struct CodegenConfig: u32 { + /// Whether to generate functions. + const FUNCTIONS = 1 << 0; + /// Whether to generate types. + const TYPES = 1 << 1; + /// Whether to generate constants. + const VARS = 1 << 2; + /// Whether to generate methods. + const METHODS = 1 << 3; + /// Whether to generate constructors + const CONSTRUCTORS = 1 << 4; + /// Whether to generate destructors. + const DESTRUCTORS = 1 << 5; + } +} + +impl CodegenConfig { + /// Returns true if functions should be generated. + pub fn functions(self) -> bool { + self.contains(CodegenConfig::FUNCTIONS) + } + + /// Returns true if types should be generated. + pub fn types(self) -> bool { + self.contains(CodegenConfig::TYPES) + } + + /// Returns true if constants should be generated. + pub fn vars(self) -> bool { + self.contains(CodegenConfig::VARS) + } + + /// Returns true if methods should be generated. + pub fn methods(self) -> bool { + self.contains(CodegenConfig::METHODS) + } + + /// Returns true if constructors should be generated. + pub fn constructors(self) -> bool { + self.contains(CodegenConfig::CONSTRUCTORS) + } + + /// Returns true if destructors should be generated. + pub fn destructors(self) -> bool { + self.contains(CodegenConfig::DESTRUCTORS) + } +} + +impl Default for CodegenConfig { + fn default() -> Self { + CodegenConfig::all() + } +} + +/// Formatting tools that can be used to format the bindings +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] +pub enum Formatter { + /// Do not format the bindings. + None, + /// Use `rustfmt` to format the bindings. + Rustfmt, + #[cfg(feature = "prettyplease")] + /// Use `prettyplease` to format the bindings. + Prettyplease, +} + +impl Default for Formatter { + fn default() -> Self { + Self::Rustfmt + } +} + +impl FromStr for Formatter { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "none" => Ok(Self::None), + "rustfmt" => Ok(Self::Rustfmt), + #[cfg(feature = "prettyplease")] + "prettyplease" => Ok(Self::Prettyplease), + _ => Err(format!("`{s}` is not a valid formatter")), + } + } +} + +impl std::fmt::Display for Formatter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + Self::None => "none", + Self::Rustfmt => "rustfmt", + #[cfg(feature = "prettyplease")] + Self::Prettyplease => "prettyplease", + }; + + std::fmt::Display::fmt(&s, f) + } +} + +/// Configure and generate Rust bindings for a C/C++ header. +/// +/// This is the main entry point to the library. +/// +/// ```ignore +/// use bindgen::builder; +/// +/// // Configure and generate bindings. +/// let bindings = builder().header("path/to/input/header") +/// .allowlist_type("SomeCoolClass") +/// .allowlist_function("do_some_cool_thing") +/// .generate()?; +/// +/// // Write the generated bindings to an output file. +/// bindings.write_to_file("path/to/output.rs")?; +/// ``` +/// +/// # Enums +/// +/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on +/// the pattern passed to several methods: +/// +/// 1. [`constified_enum_module()`](#method.constified_enum_module) +/// 2. [`bitfield_enum()`](#method.bitfield_enum) +/// 3. [`newtype_enum()`](#method.newtype_enum) +/// 4. [`rustified_enum()`](#method.rustified_enum) +/// 5. [`rustified_non_exhaustive_enum()`](#method.rustified_non_exhaustive_enum) +/// +/// For each C enum, bindgen tries to match the pattern in the following order: +/// +/// 1. Constified enum module +/// 2. Bitfield enum +/// 3. Newtype enum +/// 4. Rustified enum +/// +/// If none of the above patterns match, then bindgen will generate a set of Rust constants. +/// +/// # Clang arguments +/// +/// Extra arguments can be passed to with clang: +/// 1. [`clang_arg()`](#method.clang_arg): takes a single argument +/// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments +/// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate +/// environment variable of arguments +/// +/// Clang arguments specific to your crate should be added via the +/// `clang_arg()`/`clang_args()` methods. +/// +/// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to +/// add additional arguments. For example, to build against a different sysroot a user could set +/// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`. +/// +/// # Regular expression arguments +/// +/// Some [`Builder`] methods, such as `allowlist_*` and `blocklist_*`, allow regular +/// expressions as arguments. These regular expressions will be enclosed in parentheses and +/// anchored with `^` and `$`. So, if the argument passed is ``, the regular expression to be +/// stored will be `^()$`. +/// +/// As a consequence, regular expressions passed to `bindgen` will try to match the whole name of +/// an item instead of a section of it, which means that to match any items with the prefix +/// `prefix`, the `prefix.*` regular expression must be used. +/// +/// Certain methods, like [`Builder::allowlist_function`], use regular expressions over function +/// names. To match C++ methods, prefix the name of the type where they belong, followed by an +/// underscore. So, if the type `Foo` has a method `bar`, it can be matched with the `Foo_bar` +/// regular expression. +/// +/// Additionally, Objective-C interfaces can be matched by prefixing the regular expression with +/// `I`. For example, the `IFoo` regular expression matches the `Foo` interface, and the `IFoo_foo` +/// regular expression matches the `foo` method of the `Foo` interface. +/// +/// Releases of `bindgen` with a version lesser or equal to `0.62.0` used to accept the wildcard +/// pattern `*` as a valid regular expression. This behavior has been deprecated, and the `.*` +/// regular expression must be used instead. +#[derive(Debug, Default, Clone)] +pub struct Builder { + options: BindgenOptions, +} + +/// Construct a new [`Builder`](./struct.Builder.html). +pub fn builder() -> Builder { + Default::default() +} + +fn get_extra_clang_args( + parse_callbacks: &[Rc], +) -> Vec { + // Add any extra arguments from the environment to the clang command line. + let Some(extra_clang_args) = get_target_dependent_env_var( + parse_callbacks, + "BINDGEN_EXTRA_CLANG_ARGS", + ) else { + return vec![]; + }; + + // Try to parse it with shell quoting. If we fail, make it one single big argument. + if let Some(strings) = shlex::split(&extra_clang_args) { + return strings; + } + vec![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) + .into_iter() + .map(String::into_boxed_str), + ); + + for header in &self.options.input_headers { + self.options + .for_each_callback(|cb| cb.header_file(header.as_ref())); + } + + // 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)] + .iter() + .flat_map(|header| ["-include".into(), header.clone()]), + ); + + let input_unsaved_files = + std::mem::take(&mut self.options.input_header_contents) + .into_iter() + .map(|(name, contents)| { + clang::UnsavedFile::new(name.as_ref(), contents.as_ref()) + }) + .collect::>(); + + Bindings::generate(self.options, &input_unsaved_files) + } + + /// Preprocess and dump the input header files to disk. + /// + /// This is useful when debugging bindgen, using C-Reduce, or when filing + /// issues. The resulting file will be named something like `__bindgen.i` or + /// `__bindgen.ii` + pub fn dump_preprocessed_input(&self) -> io::Result<()> { + let clang = + clang_sys::support::Clang::find(None, &[]).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "Cannot find clang executable", + ) + })?; + + // The contents of a wrapper file that includes all the input header + // files. + let mut wrapper_contents = String::new(); + + // Whether we are working with C or C++ inputs. + let mut is_cpp = args_are_cpp(&self.options.clang_args); + + // For each input header, add `#include "$header"`. + for header in &self.options.input_headers { + is_cpp |= file_is_cpp(header); + + wrapper_contents.push_str("#include \""); + wrapper_contents.push_str(header); + wrapper_contents.push_str("\"\n"); + } + + // For each input header content, add a prefix line of `#line 0 "$name"` + // followed by the contents. + for (name, contents) in &self.options.input_header_contents { + is_cpp |= file_is_cpp(name); + + wrapper_contents.push_str("#line 0 \""); + wrapper_contents.push_str(name); + wrapper_contents.push_str("\"\n"); + wrapper_contents.push_str(contents); + } + + let wrapper_path = PathBuf::from(if is_cpp { + "__bindgen.cpp" + } else { + "__bindgen.c" + }); + + { + let mut wrapper_file = File::create(&wrapper_path)?; + wrapper_file.write_all(wrapper_contents.as_bytes())?; + } + + let mut cmd = Command::new(clang.path); + cmd.arg("-save-temps") + .arg("-E") + .arg("-C") + .arg("-c") + .arg(&wrapper_path) + .stdout(Stdio::piped()); + + for a in &self.options.clang_args { + cmd.arg(a.as_ref()); + } + + for a in get_extra_clang_args(&self.options.parse_callbacks) { + cmd.arg(a); + } + + let mut child = cmd.spawn()?; + + let mut preprocessed = child.stdout.take().unwrap(); + let mut file = File::create(if is_cpp { + "__bindgen.ii" + } else { + "__bindgen.i" + })?; + io::copy(&mut preprocessed, &mut file)?; + + if child.wait()?.success() { + Ok(()) + } else { + Err(io::Error::new( + io::ErrorKind::Other, + "clang exited with non-zero status", + )) + } + } +} + +impl BindgenOptions { + fn build(&mut self) { + const REGEX_SETS_LEN: usize = 29; + + let regex_sets: [_; REGEX_SETS_LEN] = [ + &mut self.blocklisted_types, + &mut self.blocklisted_functions, + &mut self.blocklisted_items, + &mut self.blocklisted_files, + &mut self.blocklisted_vars, + &mut self.opaque_types, + &mut self.allowlisted_vars, + &mut self.allowlisted_types, + &mut self.allowlisted_functions, + &mut self.allowlisted_files, + &mut self.allowlisted_items, + &mut self.bitfield_enums, + &mut self.constified_enums, + &mut self.constified_enum_modules, + &mut self.newtype_enums, + &mut self.newtype_global_enums, + &mut self.rustified_enums, + &mut self.rustified_non_exhaustive_enums, + &mut self.type_alias, + &mut self.new_type_alias, + &mut self.new_type_alias_deref, + &mut self.bindgen_wrapper_union, + &mut self.manually_drop_union, + &mut self.no_partialeq_types, + &mut self.no_copy_types, + &mut self.no_debug_types, + &mut self.no_default_types, + &mut self.no_hash_types, + &mut self.must_use_types, + ]; + + let record_matches = self.record_matches; + #[cfg(feature = "experimental")] + { + let sets_len = REGEX_SETS_LEN + self.abi_overrides.len(); + let names = if self.emit_diagnostics { + <[&str; REGEX_SETS_LEN]>::into_iter([ + "--blocklist-type", + "--blocklist-function", + "--blocklist-item", + "--blocklist-file", + "--blocklist-var", + "--opaque-type", + "--allowlist-type", + "--allowlist-function", + "--allowlist-var", + "--allowlist-file", + "--allowlist-item", + "--bitfield-enum", + "--newtype-enum", + "--newtype-global-enum", + "--rustified-enum", + "--rustified-enum-non-exhaustive", + "--constified-enum-module", + "--constified-enum", + "--type-alias", + "--new-type-alias", + "--new-type-alias-deref", + "--bindgen-wrapper-union", + "--manually-drop-union", + "--no-partialeq", + "--no-copy", + "--no-debug", + "--no-default", + "--no-hash", + "--must-use", + ]) + .chain((0..self.abi_overrides.len()).map(|_| "--override-abi")) + .map(Some) + .collect() + } else { + vec![None; sets_len] + }; + + for (regex_set, name) in + self.abi_overrides.values_mut().chain(regex_sets).zip(names) + { + regex_set.build_with_diagnostics(record_matches, name); + } + } + #[cfg(not(feature = "experimental"))] + for regex_set in self.abi_overrides.values_mut().chain(regex_sets) { + regex_set.build(record_matches); + } + } + + /// Update rust target version + pub fn set_rust_target(&mut self, rust_target: RustTarget) { + self.rust_target = rust_target; + } + + /// Get features supported by target Rust version + pub fn rust_features(&self) -> RustFeatures { + self.rust_features + } + + fn last_callback( + &self, + f: impl Fn(&dyn callbacks::ParseCallbacks) -> Option, + ) -> Option { + self.parse_callbacks + .iter() + .filter_map(|cb| f(cb.as_ref())) + .next_back() + } + + fn all_callbacks( + &self, + f: impl Fn(&dyn callbacks::ParseCallbacks) -> Vec, + ) -> Vec { + self.parse_callbacks + .iter() + .flat_map(|cb| f(cb.as_ref())) + .collect() + } + + fn for_each_callback(&self, f: impl Fn(&dyn callbacks::ParseCallbacks)) { + self.parse_callbacks.iter().for_each(|cb| f(cb.as_ref())); + } + + fn process_comment(&self, comment: &str) -> String { + let comment = comment::preprocess(comment); + self.last_callback(|cb| cb.process_comment(&comment)) + .unwrap_or(comment) + } +} + +#[cfg(feature = "runtime")] +fn ensure_libclang_is_loaded() { + use std::sync::{Arc, OnceLock}; + + if clang_sys::is_loaded() { + return; + } + + // XXX (issue #350): Ensure that our dynamically loaded `libclang` + // doesn't get dropped prematurely, nor is loaded multiple times + // across different threads. + + static LIBCLANG: OnceLock> = OnceLock::new(); + let libclang = LIBCLANG.get_or_init(|| { + clang_sys::load().expect("Unable to find libclang"); + clang_sys::get_library() + .expect("We just loaded libclang and it had better still be here!") + }); + + clang_sys::set_library(Some(libclang.clone())); +} + +#[cfg(not(feature = "runtime"))] +fn ensure_libclang_is_loaded() {} + +/// Error type for rust-bindgen. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub enum BindgenError { + /// The header was a folder. + FolderAsHeader(PathBuf), + /// Permissions to read the header is insufficient. + InsufficientPermissions(PathBuf), + /// The header does not exist. + NotExist(PathBuf), + /// Clang diagnosed an error. + 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 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BindgenError::FolderAsHeader(h) => { + write!(f, "'{}' is a folder", h.display()) + } + BindgenError::InsufficientPermissions(h) => { + write!(f, "insufficient permissions to read '{}'", h.display()) + } + BindgenError::NotExist(h) => { + write!(f, "header '{}' does not exist.", h.display()) + } + BindgenError::ClangDiagnostic(message) => { + write!(f, "clang diagnosed error: {message}") + } + BindgenError::Codegen(err) => { + write!(f, "codegen error: {err}") + } + BindgenError::UnsupportedEdition(edition, target) => { + write!(f, "edition {edition} is not available on Rust {target}") + } + } + } +} + +impl std::error::Error for BindgenError {} + +/// Generated Rust bindings. +#[derive(Debug)] +pub struct Bindings { + options: BindgenOptions, + module: proc_macro2::TokenStream, +} + +pub(crate) const HOST_TARGET: &str = + include_str!(concat!(env!("OUT_DIR"), "/host-target.txt")); + +// Some architecture triplets are different between rust and libclang, see #1211 +// and duplicates. +fn rust_to_clang_target(rust_target: &str) -> Box { + const TRIPLE_HYPHENS_MESSAGE: &str = "Target triple should contain hyphens"; + + let mut triple: Vec<&str> = rust_target.split_terminator('-').collect(); + + assert!(!triple.is_empty(), "{TRIPLE_HYPHENS_MESSAGE}"); + triple.resize(4, ""); + + // RISC-V + if triple[0].starts_with("riscv32") { + triple[0] = "riscv32"; + } else if triple[0].starts_with("riscv64") { + triple[0] = "riscv64"; + } + + // Apple + if triple[1] == "apple" { + if triple[0] == "aarch64" { + triple[0] = "arm64"; + } + if triple[3] == "sim" { + triple[3] = "simulator"; + } + } + + // ESP-IDF + if triple[2] == "espidf" { + triple[2] = "elf"; + } + + 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 +/// clang flags. +fn find_effective_target(clang_args: &[Box]) -> (Box, bool) { + let mut args = clang_args.iter(); + while let Some(opt) = args.next() { + if opt.starts_with("--target=") { + let mut split = opt.split('='); + split.next(); + return (split.next().unwrap().into(), true); + } + + if opt.as_ref() == "-target" { + if let Some(target) = args.next() { + return (target.clone(), true); + } + } + } + + // If we're running from a build script, try to find the cargo target. + if let Ok(t) = env::var("TARGET") { + return (rust_to_clang_target(&t), false); + } + + (rust_to_clang_target(HOST_TARGET), false) +} + +impl Bindings { + /// Generate bindings for the given options. + pub(crate) fn generate( + mut options: BindgenOptions, + 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 {}", + clang_sys::get_library().unwrap().path().display() + ); + #[cfg(not(feature = "runtime"))] + debug!("Generating bindings, libclang linked"); + + options.build(); + + let (effective_target, explicit_target) = + find_effective_target(&options.clang_args); + + let is_host_build = + rust_to_clang_target(HOST_TARGET) == effective_target; + + // NOTE: The is_host_build check wouldn't be sound normally in some + // cases if we were to call a binary (if you have a 32-bit clang and are + // building on a 64-bit system for example). But since we rely on + // opening libclang.so, it has to be the same architecture and thus the + // check is fine. + if !explicit_target && !is_host_build { + options.clang_args.insert( + 0, + format!("--target={effective_target}").into_boxed_str(), + ); + } + + fn detect_include_paths(options: &mut BindgenOptions) { + if !options.detect_include_paths { + return; + } + + // Filter out include paths and similar stuff, so we don't incorrectly + // promote them to `-isystem`. + let clang_args_for_clang_sys = { + let mut last_was_include_prefix = false; + options + .clang_args + .iter() + .filter(|arg| { + if last_was_include_prefix { + last_was_include_prefix = false; + return false; + } + + let arg = arg.as_ref(); + + // https://clang.llvm.org/docs/ClangCommandLineReference.html + // -isystem and -isystem-after are harmless. + if arg == "-I" || arg == "--include-directory" { + last_was_include_prefix = true; + return false; + } + + if arg.starts_with("-I") || + arg.starts_with("--include-directory=") + { + return false; + } + + true + }) + .map(|arg| arg.clone().into()) + .collect::>() + }; + + debug!( + "Trying to find clang with flags: {clang_args_for_clang_sys:?}" + ); + + let Some(clang) = clang_sys::support::Clang::find( + None, + &clang_args_for_clang_sys, + ) else { + return; + }; + + debug!("Found clang: {clang:?}"); + + // Whether we are working with C or C++ inputs. + let is_cpp = args_are_cpp(&options.clang_args) || + options.input_headers.iter().any(|h| file_is_cpp(h)); + + let search_paths = if is_cpp { + clang.cpp_search_paths + } else { + clang.c_search_paths + }; + + if let Some(search_paths) = search_paths { + 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()); + } + } + } + } + + detect_include_paths(&mut options); + + #[cfg(unix)] + fn can_read(perms: &std::fs::Permissions) -> bool { + use std::os::unix::fs::PermissionsExt; + perms.mode() & 0o444 > 0 + } + + #[cfg(not(unix))] + fn can_read(_: &std::fs::Permissions) -> bool { + true + } + + if let Some(h) = options.input_headers.last() { + let path = Path::new(h.as_ref()); + if let Ok(md) = std::fs::metadata(path) { + if md.is_dir() { + return Err(BindgenError::FolderAsHeader(path.into())); + } + if !can_read(&md.permissions()) { + return Err(BindgenError::InsufficientPermissions( + path.into(), + )); + } + options.clang_args.push(h.clone()); + } else { + return Err(BindgenError::NotExist(path.into())); + } + } + + for (idx, f) in input_unsaved_files.iter().enumerate() { + if idx != 0 || !options.input_headers.is_empty() { + options.clang_args.push("-include".into()); + } + options.clang_args.push(f.name.to_str().unwrap().into()); + } + + debug!("Fixed-up options: {options:?}"); + + let time_phases = options.time_phases; + let mut context = BindgenContext::new(options, input_unsaved_files); + + if is_host_build { + debug_assert_eq!( + context.target_pointer_size(), + size_of::<*mut ()>(), + "{effective_target:?} {HOST_TARGET:?}" + ); + } + + { + let _t = time::Timer::new("parse").with_output(time_phases); + parse(&mut context)?; + } + + let (module, options) = + codegen::codegen(context).map_err(BindgenError::Codegen)?; + + Ok(Bindings { options, module }) + } + + /// Write these bindings as source text to a file. + pub fn write_to_file>(&self, path: P) -> io::Result<()> { + let file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(path.as_ref())?; + self.write(Box::new(file))?; + Ok(()) + } + + /// Write these bindings as source text to the given `Write`able. + pub fn write<'a>(&self, mut writer: Box) -> io::Result<()> { + const NL: &str = if cfg!(windows) { "\r\n" } else { "\n" }; + + if !self.options.disable_header_comment { + let version = + option_env!("CARGO_PKG_VERSION").unwrap_or("(unknown version)"); + write!( + writer, + "/* automatically generated by rust-bindgen {version} */{NL}{NL}", + )?; + } + + for line in &self.options.raw_lines { + writer.write_all(line.as_bytes())?; + writer.write_all(NL.as_bytes())?; + } + + if !self.options.raw_lines.is_empty() { + writer.write_all(NL.as_bytes())?; + } + + match self.format_tokens(&self.module) { + Ok(formatted_bindings) => { + writer.write_all(formatted_bindings.as_bytes())?; + } + Err(err) => { + eprintln!( + "Failed to run rustfmt: {err} (non-fatal, continuing)" + ); + writer.write_all(self.module.to_string().as_bytes())?; + } + } + Ok(()) + } + + /// Gets the rustfmt path to rustfmt the generated bindings. + fn rustfmt_path(&self) -> Cow<'_, Path> { + debug_assert!(matches!(self.options.formatter, Formatter::Rustfmt)); + if let Some(ref p) = self.options.rustfmt_path { + 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")) + } + } + + /// Formats a token stream with the formatter set up in `BindgenOptions`. + fn format_tokens( + &self, + tokens: &proc_macro2::TokenStream, + ) -> io::Result { + let _t = time::Timer::new("rustfmt_generated_string") + .with_output(self.options.time_phases); + + match self.options.formatter { + Formatter::None => return Ok(tokens.to_string()), + #[cfg(feature = "prettyplease")] + Formatter::Prettyplease => { + return Ok(prettyplease::unparse(&syn::parse_quote!(#tokens))); + } + Formatter::Rustfmt => (), + } + + let rustfmt = self.rustfmt_path(); + let mut cmd = Command::new(&*rustfmt); + + cmd.stdin(Stdio::piped()).stdout(Stdio::piped()); + + if let Some(path) = self + .options + .rustfmt_configuration_file + .as_ref() + .and_then(|f| f.to_str()) + { + 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(); + + let source = tokens.to_string(); + + // Write to stdin in a new thread, so that we can read from stdout on this + // thread. This keeps the child from blocking on writing to its stdout which + // might block us from writing to its stdin. + let stdin_handle = ::std::thread::spawn(move || { + let _ = child_stdin.write_all(source.as_bytes()); + source + }); + + let mut output = vec![]; + io::copy(&mut child_stdout, &mut output)?; + + let status = child.wait()?; + let source = stdin_handle.join().expect( + "The thread writing to rustfmt's stdin doesn't do \ + anything that could panic", + ); + + match String::from_utf8(output) { + Ok(bindings) => match status.code() { + Some(0) => Ok(bindings), + Some(2) => Err(io::Error::new( + io::ErrorKind::Other, + "Rustfmt parsing errors.".to_string(), + )), + Some(3) => { + rustfmt_non_fatal_error_diagnostic( + "Rustfmt could not format some lines", + &self.options, + ); + Ok(bindings) + } + _ => Err(io::Error::new( + io::ErrorKind::Other, + "Internal rustfmt error".to_string(), + )), + }, + _ => Ok(source), + } + } +} + +fn rustfmt_non_fatal_error_diagnostic(msg: &str, _options: &BindgenOptions) { + warn!("{msg}"); + + #[cfg(feature = "experimental")] + if _options.emit_diagnostics { + use crate::diagnostics::{Diagnostic, Level}; + + Diagnostic::default() + .with_title(msg, Level::Warning) + .add_annotation( + "The bindings will be generated but not formatted.", + Level::Note, + ) + .display(); + } +} + +impl std::fmt::Display for Bindings { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut bytes = vec![]; + self.write(Box::new(&mut bytes) as Box) + .expect("writing to a vec cannot fail"); + f.write_str( + std::str::from_utf8(&bytes) + .expect("we should only write bindings that are valid utf-8"), + ) + } +} + +/// Determines whether the given cursor is in any of the files matched by the +/// options. +fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { + ctx.options().builtins || !cursor.is_builtin() +} + +/// Parse one `Item` from the Clang cursor. +fn parse_one( + ctx: &mut BindgenContext, + cursor: clang::Cursor, + parent: Option, +) { + if !filter_builtins(ctx, &cursor) { + return; + } + + match Item::parse(cursor, parent, ctx) { + Ok(..) => {} + Err(ParseError::Continue) => {} + Err(ParseError::Recurse) => { + cursor + .visit_sorted(ctx, |ctx, child| parse_one(ctx, child, parent)); + } + } +} + +/// Parse the Clang AST into our `Item` internal representation. +fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { + use clang_sys::*; + + let mut error = None; + for d in &context.translation_unit().diags() { + let msg = d.format(); + let is_err = d.severity() >= CXDiagnostic_Error; + if is_err { + let error = error.get_or_insert_with(String::new); + error.push_str(&msg); + error.push('\n'); + } else { + eprintln!("clang diag: {msg}"); + } + } + + if let Some(message) = error { + return Err(BindgenError::ClangDiagnostic(message)); + } + + let cursor = context.translation_unit().cursor(); + + if context.options().emit_ast { + fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { + if cur.is_builtin() { + CXChildVisit_Continue + } else { + clang::ast_dump(cur, 0) + } + } + cursor.visit(|cur| dump_if_not_builtin(&cur)); + } + + let root = context.root_module(); + context.with_module(root, |ctx| { + cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None)); + }); + + assert_eq!( + context.current_module(), + context.root_module(), + "How did this happen?" + ); + Ok(()) +} + +/// Extracted Clang version data +#[derive(Debug)] +pub struct ClangVersion { + /// Major and minor semver, if parsing was successful + pub parsed: Option<(u32, u32)>, + /// full version string + pub full: String, +} + +/// Get the major and the minor semver numbers of Clang's version +pub fn clang_version() -> ClangVersion { + ensure_libclang_is_loaded(); + + //Debian clang version 11.0.1-2 + let raw_v: String = clang::extract_clang_version(); + let split_v: Option> = raw_v + .split_whitespace() + .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 { + let maybe_major = v[0].parse::(); + let maybe_minor = v[1].parse::(); + if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) { + return ClangVersion { + parsed: Some((major, minor)), + full: raw_v.clone(), + }; + } + } + } + ClangVersion { + parsed: None, + full: raw_v.clone(), + } +} + +fn env_var + AsRef>( + parse_callbacks: &[Rc], + key: K, +) -> Result { + for callback in parse_callbacks { + callback.read_env_var(key.as_ref()); + } + env::var(key) +} + +/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found. +fn get_target_dependent_env_var( + parse_callbacks: &[Rc], + var: &str, +) -> Option { + if let Ok(target) = env_var(parse_callbacks, "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('-', "_")), + ) { + return Some(v); + } + } + + env_var(parse_callbacks, var).ok() +} + +/// 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 +/// generated bindings whenever any of the files included from the header change: +/// ``` +/// use bindgen::builder; +/// let bindings = builder() +/// .header("path/to/input/header") +/// .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) +/// .generate(); +/// ``` +#[derive(Debug)] +pub struct CargoCallbacks { + rerun_on_header_files: bool, +} + +/// Create a new `CargoCallbacks` value with [`CargoCallbacks::rerun_on_header_files`] disabled. +/// +/// This constructor has been deprecated in favor of [`CargoCallbacks::new`] where +/// [`CargoCallbacks::rerun_on_header_files`] is enabled by default. +#[deprecated = "Use `CargoCallbacks::new()` instead. Please, check the documentation for further information."] +pub const CargoCallbacks: CargoCallbacks = CargoCallbacks { + rerun_on_header_files: false, +}; + +impl CargoCallbacks { + /// Create a new `CargoCallbacks` value. + pub fn new() -> Self { + Self { + rerun_on_header_files: true, + } + } + + /// Whether Cargo should re-run the build script if any of the input header files has changed. + /// + /// This option is enabled by default unless the deprecated [`const@CargoCallbacks`] + /// constructor is used. + pub fn rerun_on_header_files(mut self, doit: bool) -> Self { + self.rerun_on_header_files = doit; + self + } +} + +impl Default for CargoCallbacks { + fn default() -> Self { + Self::new() + } +} + +impl callbacks::ParseCallbacks for CargoCallbacks { + fn header_file(&self, filename: &str) { + if self.rerun_on_header_files { + println!("cargo:rerun-if-changed={filename}"); + } + } + + fn include_file(&self, filename: &str) { + println!("cargo:rerun-if-changed={filename}"); + } + + fn read_env_var(&self, key: &str) { + println!("cargo:rerun-if-env-changed={key}"); + } +} + +/// Test `command_line_flag` function. +#[test] +fn commandline_flag_unit_test_function() { + //Test 1 + let bindings = builder(); + let command_line_flags = bindings.command_line_flags(); + + let test_cases = [ + "--rust-target", + "--no-derive-default", + "--generate", + "functions,types,vars,methods,constructors,destructors", + ] + .iter() + .map(|&x| x.into()) + .collect::>(); + + assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); + + //Test 2 + let bindings = builder() + .header("input_header") + .allowlist_type("Distinct_Type") + .allowlist_function("safe_function"); + + let command_line_flags = bindings.command_line_flags(); + let test_cases = [ + "--rust-target", + "input_header", + "--no-derive-default", + "--generate", + "functions,types,vars,methods,constructors,destructors", + "--allowlist-type", + "Distinct_Type", + "--allowlist-function", + "safe_function", + ] + .iter() + .map(|&x| x.into()) + .collect::>(); + println!("{command_line_flags:?}"); + + assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); +} + +#[test] +fn test_rust_to_clang_target() { + assert_eq!( + rust_to_clang_target("aarch64-apple-ios").as_ref(), + "arm64-apple-ios" + ); +} + +#[test] +fn test_rust_to_clang_target_riscv() { + assert_eq!( + rust_to_clang_target("riscv64gc-unknown-linux-gnu").as_ref(), + "riscv64-unknown-linux-gnu" + ); + assert_eq!( + rust_to_clang_target("riscv64imac-unknown-none-elf").as_ref(), + "riscv64-unknown-none-elf" + ); + assert_eq!( + rust_to_clang_target("riscv32imc-unknown-none-elf").as_ref(), + "riscv32-unknown-none-elf" + ); + assert_eq!( + rust_to_clang_target("riscv32imac-unknown-none-elf").as_ref(), + "riscv32-unknown-none-elf" + ); + assert_eq!( + rust_to_clang_target("riscv32imafc-unknown-none-elf").as_ref(), + "riscv32-unknown-none-elf" + ); + assert_eq!( + rust_to_clang_target("riscv32i-unknown-none-elf").as_ref(), + "riscv32-unknown-none-elf" + ); +} + +#[test] +fn test_rust_to_clang_target_espidf() { + assert_eq!( + rust_to_clang_target("riscv32imc-esp-espidf").as_ref(), + "riscv32-esp-elf" + ); + assert_eq!( + rust_to_clang_target("xtensa-esp32-espidf").as_ref(), + "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/src/log_stubs.rs b/bindgen/log_stubs.rs similarity index 88% rename from src/log_stubs.rs rename to bindgen/log_stubs.rs index 8315983128..51d2f81fd1 100644 --- a/src/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 new file mode 100644 index 0000000000..83103fdaf4 --- /dev/null +++ b/bindgen/options/as_args.rs @@ -0,0 +1,52 @@ +use std::path::PathBuf; + +use crate::regex_set::RegexSet; + +/// Trait used to turn [`crate::BindgenOptions`] fields into CLI args. +pub(super) trait AsArgs { + fn as_args(&self, args: &mut Vec, flag: &str); +} + +/// If the `bool` is `true`, `flag` is pushed into `args`. +/// +/// be careful about the truth value of the field as some options, like `--no-layout-tests`, are +/// actually negations of the fields. +impl AsArgs for bool { + fn as_args(&self, args: &mut Vec, flag: &str) { + if *self { + args.push(flag.to_string()); + } + } +} + +/// Iterate over all the items of the `RegexSet` and push `flag` followed by the item into `args` +/// for each item. +impl AsArgs for RegexSet { + fn as_args(&self, args: &mut Vec, flag: &str) { + for item in self.get_items() { + args.extend_from_slice(&[flag.to_owned(), item.clone().into()]); + } + } +} + +/// If the `Option` is `Some(value)`, push `flag` followed by `value`. +impl AsArgs for Option { + fn as_args(&self, args: &mut Vec, flag: &str) { + if let Some(string) = self { + args.extend_from_slice(&[flag.to_owned(), string.clone()]); + } + } +} + +/// If the `Option` is `Some(path)`, push `flag` followed by the [`std::path::Path::display`] +/// representation of `path`. +impl AsArgs for Option { + fn as_args(&self, args: &mut Vec, flag: &str) { + if let Some(path) = self { + args.extend_from_slice(&[ + flag.to_owned(), + path.display().to_string(), + ]); + } + } +} diff --git a/bindgen/options/cli.rs b/bindgen/options/cli.rs new file mode 100644 index 0000000000..972b487c25 --- /dev/null +++ b/bindgen/options/cli.rs @@ -0,0 +1,1161 @@ +#![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, + RustTarget, +}; +use clap::{ + error::{Error, ErrorKind}, + CommandFactory, Parser, +}; +use proc_macro2::TokenStream; +use std::io; +use std::path::{Path, PathBuf}; +use std::str::FromStr; +use std::{fs::File, process::exit}; + +fn rust_target_help() -> String { + format!( + "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 { + let mut config = CodegenConfig::empty(); + for what in what_to_generate.split(',') { + match what { + "functions" => config.insert(CodegenConfig::FUNCTIONS), + "types" => config.insert(CodegenConfig::TYPES), + "vars" => config.insert(CodegenConfig::VARS), + "methods" => config.insert(CodegenConfig::METHODS), + "constructors" => config.insert(CodegenConfig::CONSTRUCTORS), + "destructors" => config.insert(CodegenConfig::DESTRUCTORS), + otherwise => { + return Err(Error::raw( + ErrorKind::InvalidValue, + format!("Unknown codegen item kind: {otherwise}"), + )); + } + } + } + + Ok(config) +} + +fn parse_rustfmt_config_path(path_str: &str) -> Result { + let path = Path::new(path_str); + + if !path.is_absolute() { + return Err(Error::raw( + ErrorKind::InvalidValue, + "--rustfmt-configuration-file needs to be an absolute path!", + )); + } + + if path.to_str().is_none() { + return Err(Error::raw( + ErrorKind::InvalidUtf8, + "--rustfmt-configuration-file contains non-valid UTF8 characters.", + )); + } + + Ok(path.to_path_buf()) +} + +fn parse_abi_override(abi_override: &str) -> Result<(Abi, String), Error> { + let (regex, abi_str) = abi_override + .rsplit_once('=') + .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?; + + let abi = abi_str + .parse() + .map_err(|err| Error::raw(ErrorKind::InvalidValue, err))?; + + Ok((abi, regex.to_owned())) +} + +fn parse_custom_derive( + custom_derive: &str, +) -> Result<(Vec, String), Error> { + let (regex, derives) = custom_derive + .rsplit_once('=') + .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?; + + let derives = derives.split(',').map(|s| s.to_owned()).collect(); + + Ok((derives, regex.to_owned())) +} + +fn parse_custom_attribute( + custom_attribute: &str, +) -> Result<(Vec, String), Error> { + let mut brace_level = 0; + let (regex, attributes) = custom_attribute + .rsplit_once(|c| { + match c { + ']' => brace_level += 1, + '[' => brace_level -= 1, + _ => {} + } + c == '=' && brace_level == 0 + }) + .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?; + + let mut brace_level = 0; + let attributes = attributes + .split(|c| { + match c { + ']' => brace_level += 1, + '[' => brace_level -= 1, + _ => {} + } + c == ',' && brace_level == 0 + }) + .map(|s| s.to_owned()) + .collect::>(); + + for attribute in &attributes { + if let Err(err) = TokenStream::from_str(attribute) { + return Err(Error::raw(ErrorKind::InvalidValue, err)); + } + } + + Ok((attributes, regex.to_owned())) +} + +#[derive(Parser, Debug)] +#[clap( + about = "Generates Rust bindings from C/C++ headers.", + override_usage = "bindgen
-- ...", + trailing_var_arg = true +)] +#[allow(clippy::doc_markdown)] +struct BindgenCommand { + /// C or C++ header file. + header: Option, + /// Path to write depfile to. + #[arg(long)] + depfile: Option, + /// The default STYLE of code used to generate enums. + #[arg(long, value_name = "STYLE")] + default_enum_style: Option, + /// Mark any enum whose name matches REGEX as a set of bitfield flags. + #[arg(long, value_name = "REGEX")] + bitfield_enum: Vec, + /// Mark any enum whose name matches REGEX as a newtype. + #[arg(long, value_name = "REGEX")] + newtype_enum: Vec, + /// Mark any enum whose name matches REGEX as a global newtype. + #[arg(long, value_name = "REGEX")] + newtype_global_enum: Vec, + /// Mark any enum whose name matches REGEX as a Rust enum. + #[arg(long, value_name = "REGEX")] + rustified_enum: Vec, + /// Mark any enum whose name matches REGEX as a non-exhaustive Rust enum. + #[arg(long, value_name = "REGEX")] + rustified_non_exhaustive_enum: Vec, + /// Mark any enum whose name matches REGEX as a series of constants. + #[arg(long, value_name = "REGEX")] + constified_enum: Vec, + /// Mark any enum whose name matches REGEX as a module of constants. + #[arg(long, value_name = "REGEX")] + constified_enum_module: Vec, + /// The default signed/unsigned TYPE for C macro constants. + #[arg(long, value_name = "TYPE")] + default_macro_constant_type: Option, + /// The default STYLE of code used to generate typedefs. + #[arg(long, value_name = "STYLE")] + default_alias_style: Option, + /// Mark any typedef alias whose name matches REGEX to use normal type aliasing. + #[arg(long, value_name = "REGEX")] + normal_alias: Vec, + /// Mark any typedef alias whose name matches REGEX to have a new type generated for it. + #[arg(long, value_name = "REGEX")] + new_type_alias: Vec, + /// Mark any typedef alias whose name matches REGEX to have a new type with Deref and DerefMut to the inner type. + #[arg(long, value_name = "REGEX")] + new_type_alias_deref: Vec, + /// The default STYLE of code used to generate unions with non-Copy members. Note that ManuallyDrop was first stabilized in Rust 1.20.0. + #[arg(long, value_name = "STYLE")] + default_non_copy_union_style: Option, + /// Mark any union whose name matches REGEX and who has a non-Copy member to use a bindgen-generated wrapper for fields. + #[arg(long, value_name = "REGEX")] + bindgen_wrapper_union: Vec, + /// Mark any union whose name matches REGEX and who has a non-Copy member to use ManuallyDrop (stabilized in Rust 1.20.0) for fields. + #[arg(long, value_name = "REGEX")] + manually_drop_union: Vec, + /// Mark TYPE as hidden. + #[arg(long, value_name = "TYPE")] + blocklist_type: Vec, + /// Mark FUNCTION as hidden. + #[arg(long, value_name = "FUNCTION")] + blocklist_function: Vec, + /// Mark ITEM as hidden. + #[arg(long, value_name = "ITEM")] + blocklist_item: Vec, + /// Mark FILE as hidden. + #[arg(long, value_name = "FILE")] + blocklist_file: Vec, + /// Mark VAR as hidden. + #[arg(long, value_name = "VAR")] + blocklist_var: Vec, + /// Avoid generating layout tests for any type. + #[arg(long)] + no_layout_tests: bool, + /// Avoid deriving Copy on any type. + #[arg(long)] + no_derive_copy: bool, + /// Avoid deriving Debug on any type. + #[arg(long)] + no_derive_debug: bool, + /// Avoid deriving Default on any type. + #[arg(long, hide = true)] + no_derive_default: bool, + /// Create a Debug implementation if it cannot be derived automatically. + #[arg(long)] + impl_debug: bool, + /// Create a PartialEq implementation if it cannot be derived automatically. + #[arg(long)] + impl_partialeq: bool, + /// Derive Default on any type. + #[arg(long)] + with_derive_default: bool, + /// Derive Hash on any type. + #[arg(long)] + with_derive_hash: bool, + /// Derive PartialEq on any type. + #[arg(long)] + with_derive_partialeq: bool, + /// Derive PartialOrd on any type. + #[arg(long)] + with_derive_partialord: bool, + /// Derive Eq on any type. + #[arg(long)] + with_derive_eq: bool, + /// Derive Ord on any type. + #[arg(long)] + with_derive_ord: bool, + /// Avoid including doc comments in the output, see: + #[arg(long)] + no_doc_comments: bool, + /// Disable allowlisting types recursively. This will cause bindgen to emit Rust code that won't compile! See the `bindgen::Builder::allowlist_recursively` method's documentation for details. + #[arg(long)] + no_recursive_allowlist: bool, + /// 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, + /// Generate string constants as `&CStr` instead of `&[u8]`. + #[arg(long)] + generate_cstr: bool, + /// Use extern crate instead of use for block. + #[arg(long)] + block_extern_crate: bool, + /// Do not trust the libclang-provided mangling + #[arg(long)] + distrust_clang_mangling: bool, + /// Output bindings for builtin definitions, e.g. __builtin_va_list. + #[arg(long)] + builtins: bool, + /// Use the given PREFIX before raw types instead of ::std::os::raw. + #[arg(long, value_name = "PREFIX")] + ctypes_prefix: Option, + /// Use the given PREFIX for anonymous fields. + #[arg(long, value_name = "PREFIX")] + anon_fields_prefix: Option, + /// Time the different bindgen phases and print to stderr + #[arg(long)] + time_phases: bool, + /// Output the Clang AST for debugging purposes. + #[arg(long)] + emit_clang_ast: bool, + /// Output our internal IR for debugging purposes. + #[arg(long)] + emit_ir: bool, + /// Dump a graphviz dot file to PATH. + #[arg(long, value_name = "PATH")] + emit_ir_graphviz: Option, + /// Enable support for C++ namespaces. + #[arg(long)] + enable_cxx_namespaces: bool, + /// Disable namespacing via mangling, causing bindgen to generate names like `Baz` instead of `foo_bar_Baz` for an input name `foo::bar::Baz`. + #[arg(long)] + disable_name_namespacing: bool, + /// Disable nested struct naming, causing bindgen to generate names like `bar` instead of `foo_bar` for a nested definition `struct foo { struct bar { } b; };`. + #[arg(long)] + disable_nested_struct_naming: bool, + /// Disable support for native Rust unions. + #[arg(long)] + disable_untagged_union: bool, + /// Suppress insertion of bindgen's version identifier into generated bindings. + #[arg(long)] + disable_header_comment: bool, + /// Do not generate bindings for functions or methods. This is useful when you only care about struct layouts. + #[arg(long)] + ignore_functions: bool, + /// Generate only given items, split by commas. Valid values are `functions`,`types`, `vars`, `methods`, `constructors` and `destructors`. + #[arg(long, value_parser = parse_codegen_config)] + generate: Option, + /// Do not generate bindings for methods. + #[arg(long)] + ignore_methods: bool, + /// Do not automatically convert floats to f32/f64. + #[arg(long)] + no_convert_floats: bool, + /// Do not prepend the enum name to constant or newtype variants. + #[arg(long)] + no_prepend_enum_name: bool, + /// Do not try to detect default include paths + #[arg(long)] + no_include_path_detection: bool, + /// Try to fit macro constants into types smaller than u32/i32 + #[arg(long)] + fit_macro_constant_types: bool, + /// Mark TYPE as opaque. + #[arg(long, value_name = "TYPE")] + opaque_type: Vec, + /// Write Rust bindings to OUTPUT. + #[arg(long, short, value_name = "OUTPUT")] + output: Option, + /// Add a raw line of Rust code at the beginning of output. + #[arg(long)] + raw_line: Vec, + /// Add a RAW_LINE of Rust code to a given module with name MODULE_NAME. + #[arg(long, number_of_values = 2, value_names = ["MODULE_NAME", "RAW_LINE"])] + 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, + /// Conservatively generate inline namespaces to avoid name conflicts. + #[arg(long)] + conservative_inline_namespaces: bool, + /// Allowlist all the free-standing functions matching REGEX. Other non-allowlisted functions will not be generated. + #[arg(long, value_name = "REGEX")] + allowlist_function: Vec, + /// Generate inline functions. + #[arg(long)] + generate_inline_functions: bool, + /// Only generate types matching REGEX. Other non-allowlisted types will not be generated. + #[arg(long, value_name = "REGEX")] + allowlist_type: Vec, + /// Allowlist all the free-standing variables matching REGEX. Other non-allowlisted variables will not be generated. + #[arg(long, value_name = "REGEX")] + allowlist_var: Vec, + /// Allowlist all contents of PATH. + #[arg(long, value_name = "PATH")] + allowlist_file: Vec, + /// Allowlist all items matching REGEX. Other non-allowlisted items will not be generated. + #[arg(long, value_name = "REGEX")] + allowlist_item: Vec, + /// Print verbose error messages. + #[arg(long)] + verbose: bool, + /// Preprocess and dump the input header files to disk. Useful when debugging bindgen, using C-Reduce, or when filing issues. The resulting file will be named something like `__bindgen.i` or `__bindgen.ii`. + #[arg(long)] + dump_preprocessed_input: bool, + /// Do not record matching items in the regex sets. This disables reporting of unused items. + #[arg(long)] + no_record_matches: bool, + /// Do not bind size_t as usize (useful on platforms where those types are incompatible). + #[arg(long = "no-size_t-is-usize")] + no_size_t_is_usize: bool, + /// Do not format the generated bindings with rustfmt. This option is deprecated, please use + /// `--formatter=none` instead. + #[arg(long)] + no_rustfmt_bindings: bool, + /// Which FORMATTER should be used for the bindings + #[arg( + long, + value_name = "FORMATTER", + conflicts_with = "no_rustfmt_bindings" + )] + formatter: Option, + /// The absolute PATH to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter sets `formatter` to `rustfmt`. + #[arg(long, value_name = "PATH", conflicts_with = "no_rustfmt_bindings", value_parser=parse_rustfmt_config_path)] + rustfmt_configuration_file: Option, + /// Avoid deriving PartialEq for types matching REGEX. + #[arg(long, value_name = "REGEX")] + no_partialeq: Vec, + /// Avoid deriving Copy and Clone for types matching REGEX. + #[arg(long, value_name = "REGEX")] + no_copy: Vec, + /// Avoid deriving Debug for types matching REGEX. + #[arg(long, value_name = "REGEX")] + no_debug: Vec, + /// Avoid deriving/implementing Default for types matching REGEX. + #[arg(long, value_name = "REGEX")] + no_default: Vec, + /// Avoid deriving Hash for types matching REGEX. + #[arg(long, value_name = "REGEX")] + no_hash: Vec, + /// Add `#[must_use]` annotation to types matching REGEX. + #[arg(long, value_name = "REGEX")] + must_use_type: Vec, + /// Enables detecting unexposed attributes in functions (slow). Used to generate `#[must_use]` annotations. + #[arg(long)] + enable_function_attribute_detection: bool, + /// Use `*const [T; size]` instead of `*const T` for C arrays + #[arg(long)] + use_array_pointers_in_arguments: bool, + /// 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, + /// Require successful linkage to all functions in the library. + #[arg(long)] + dynamic_link_require_all: bool, + /// Prefix the name of exported symbols. + #[arg(long)] + prefix_link_name: Option, + /// Makes generated bindings `pub` only for items if the items are publicly accessible in C++. + #[arg(long)] + respect_cxx_access_specs: bool, + /// Always translate enum integer types to native Rust integer types. + #[arg(long)] + translate_enum_integer_types: bool, + /// Generate types with C style naming. + #[arg(long)] + c_naming: bool, + /// 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, + /// Enables sorting of code generation in a predefined manner. + #[arg(long)] + sort_semantically: bool, + /// Deduplicates extern blocks. + #[arg(long)] + merge_extern_blocks: bool, + /// Overrides the ABI of functions matching REGEX. The OVERRIDE value must be of the shape REGEX=ABI where ABI can be one of C, stdcall, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind<.> + #[arg(long, value_name = "OVERRIDE", value_parser = parse_abi_override)] + override_abi: Vec<(Abi, String)>, + /// Wrap unsafe operations in unsafe blocks. + #[arg(long)] + wrap_unsafe_ops: bool, + /// Enable fallback for clang macro parsing. + #[arg(long)] + clang_macro_fallback: bool, + /// Set path for temporary files generated by fallback for clang macro parsing. + #[arg(long)] + clang_macro_fallback_build_dir: Option, + /// 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 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 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 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 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 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 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 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 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)] + 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, 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, 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. + #[arg(long, value_name = "SHELL")] + generate_shell_completions: Option, + /// Enables experimental features. + #[arg(long)] + experimental: bool, + /// Prints the version, and exits + #[arg(short = 'V', long)] + version: bool, + /// Arguments to be passed straight through to clang. + clang_args: Vec, +} + +/// Construct a new [`Builder`](./struct.Builder.html) from command line flags. +pub fn builder_from_flags( + args: I, +) -> Result<(Builder, Box, bool), io::Error> +where + I: Iterator, +{ + let command = BindgenCommand::parse_from(args); + + let BindgenCommand { + header, + depfile, + 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, + 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, + no_layout_tests, + no_derive_copy, + no_derive_debug, + no_derive_default, + impl_debug, + impl_partialeq, + with_derive_default, + with_derive_hash, + with_derive_partialeq, + with_derive_partialord, + with_derive_eq, + with_derive_ord, + no_doc_comments, + no_recursive_allowlist, + objc_extern_crate, + nonnull_references, + generate_block, + generate_cstr, + block_extern_crate, + distrust_clang_mangling, + builtins, + ctypes_prefix, + anon_fields_prefix, + time_phases, + emit_clang_ast, + emit_ir, + emit_ir_graphviz, + enable_cxx_namespaces, + disable_name_namespacing, + disable_nested_struct_naming, + disable_untagged_union, + disable_header_comment, + ignore_functions, + generate, + ignore_methods, + no_convert_floats, + no_prepend_enum_name, + no_include_path_detection, + fit_macro_constant_types, + opaque_type, + output, + raw_line, + module_raw_line, + rust_target, + rust_edition, + use_core, + conservative_inline_namespaces, + allowlist_function, + generate_inline_functions, + allowlist_type, + allowlist_var, + allowlist_file, + allowlist_item, + verbose, + dump_preprocessed_input, + no_record_matches, + no_size_t_is_usize, + no_rustfmt_bindings, + formatter, + rustfmt_configuration_file, + no_partialeq, + no_copy, + no_debug, + no_default, + no_hash, + must_use_type, + 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, + 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, + wrap_unsafe_ops, + clang_macro_fallback, + clang_macro_fallback_build_dir, + flexarray_dst, + with_derive_custom, + with_derive_custom_struct, + with_derive_custom_enum, + with_derive_custom_union, + with_attribute_custom, + with_attribute_custom_struct, + with_attribute_custom_enum, + with_attribute_custom_union, + wrap_static_fns, + 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: _, + version, + clang_args, + } = command; + + if let Some(shell) = generate_shell_completions { + clap_complete::generate( + shell, + &mut BindgenCommand::command(), + "bindgen", + &mut io::stdout(), + ); + + exit(0) + } + + if version { + println!( + "bindgen {}", + option_env!("CARGO_PKG_VERSION").unwrap_or("unknown") + ); + if verbose { + println!("Clang: {}", crate::clang_version().full); + } + + exit(0) + } + + if header.is_none() { + return Err(io::Error::new(io::ErrorKind::Other, "Header not found")); + } + + let mut builder = builder(); + + #[derive(Debug)] + struct PrefixLinkNameCallback { + prefix: String, + } + + 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) + } + } + + #[derive(Debug)] + struct CustomDeriveCallback { + derives: Vec, + kind: Option, + regex_set: RegexSet, + } + + impl 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: &DeriveInfo<'_>) -> Vec { + if self.kind.map_or(true, |kind| kind == info.kind) && + self.regex_set.matches(info.name) + { + return self.derives.clone(); + } + vec![] + } + } + + #[derive(Debug)] + struct CustomAttributeCallback { + attributes: Vec, + kind: Option, + regex_set: RegexSet, + } + + impl 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: &AttributeInfo<'_>) -> Vec { + if self.kind.map_or(true, |kind| kind == info.kind) && + self.regex_set.matches(info.name) + { + return self.attributes.clone(); + } + vec![] + } + } + + /// 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)*}) + } + } + } + + 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() { + let line = values.next().unwrap(); + builder = builder.module_raw_line(module, line); + } + + let output = if let Some(path) = &output { + let file = File::create(path)?; + if let Some(depfile) = depfile { + builder = builder.depfile(path, depfile); + } + Box::new(io::BufWriter::new(file)) as Box + } else { + if let Some(depfile) = depfile { + builder = builder.depfile("-", depfile); + } + Box::new(io::BufWriter::new(io::stdout())) as Box + }; + + if dump_preprocessed_input { + builder.dump_preprocessed_input()?; + } + + if let Some(path) = rustfmt_configuration_file { + builder = builder.rustfmt_configuration_file(Some(path)); + } + + for (custom_derives, kind, _name) in [ + (with_derive_custom, None, "--with-derive-custom"), + ( + with_derive_custom_struct, + Some(TypeKind::Struct), + "--with-derive-custom-struct", + ), + ( + with_derive_custom_enum, + Some(TypeKind::Enum), + "--with-derive-custom-enum", + ), + ( + with_derive_custom_union, + Some(TypeKind::Union), + "--with-derive-custom-union", + ), + ] { + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + + for (derives, regex) in custom_derives { + 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, + kind, + regex_set, + })); + } + } + + for (custom_attributes, kind, _name) in [ + (with_attribute_custom, None, "--with-attribute-custom"), + ( + with_attribute_custom_struct, + Some(TypeKind::Struct), + "--with-attribute-custom-struct", + ), + ( + with_attribute_custom_enum, + Some(TypeKind::Enum), + "--with-attribute-custom-enum", + ), + ( + with_attribute_custom_union, + Some(TypeKind::Union), + "--with-attribute-custom-union", + ), + ] { + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + + for (attributes, regex) in custom_attributes { + 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 { + attributes, + kind, + regex_set, + })); + } + } + + #[cfg(feature = "experimental")] + if emit_diagnostics { + builder = builder.emit_diagnostics(); + } + + Ok((builder, output, verbose)) +} + +/// 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); + } + + builder + } +} + +/// 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 + } +} + +/// 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/helpers.rs b/bindgen/options/helpers.rs new file mode 100644 index 0000000000..1816c72b57 --- /dev/null +++ b/bindgen/options/helpers.rs @@ -0,0 +1,43 @@ +/// Helper function that appends extra documentation to [`crate::Builder`] methods that support regular +/// expressions in their input. +macro_rules! regex_option { + ($(#[$attrs:meta])* pub fn $($tokens:tt)*) => { + $(#[$attrs])* + /// + /// Regular expressions are supported. Check the [regular expression + /// arguments](./struct.Builder.html#regular-expression-arguments) section and the + /// [regex](https://docs.rs/regex) crate documentation for further information. + pub fn $($tokens)* + }; +} + +/// Helper macro to set the default value of each option. +/// +/// This macro is an internal implementation detail of the `options` macro and should not be used +/// directly. +macro_rules! default { + () => { + Default::default() + }; + ($expr:expr) => { + $expr + }; +} + +/// Helper macro to set the conversion to CLI arguments for each option. +/// +/// This macro is an internal implementation detail of the `options` macro and should not be used +/// directly. +macro_rules! as_args { + ($flag:literal) => { + |field, args| AsArgs::as_args(field, args, $flag) + }; + ($expr:expr) => { + $expr + }; +} + +/// Helper function to ignore an option when converting it into CLI arguments. +/// +/// This function is only used inside `options` and should not be used in other contexts. +pub(super) fn ignore(_: &T, _: &mut Vec) {} diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs new file mode 100644 index 0000000000..b9b33a850b --- /dev/null +++ b/bindgen/options/mod.rs @@ -0,0 +1,2332 @@ +//! Declarations and setter methods for `bindgen` options. +//! +//! The main entry point of this module is the `options` macro. +#[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::{RustEdition, RustFeatures, RustTarget}; +use crate::regex_set::RegexSet; +use crate::Abi; +use crate::Builder; +use crate::CodegenConfig; +use crate::FieldVisibilityKind; +use crate::Formatter; +use crate::HashMap; +use crate::DEFAULT_ANON_FIELDS_PREFIX; + +use std::env; +use std::path::{Path, PathBuf}; +use std::rc::Rc; + +use as_args::AsArgs; +use helpers::ignore; + +/// Macro used to generate the [`BindgenOptions`] type and the [`Builder`] setter methods for each +/// one of the fields of `BindgenOptions`. +/// +/// The input format of this macro resembles a `struct` pattern. Each field of the `BindgenOptions` +/// type is declared by adding the name of the field and its type using the `name: type` syntax and +/// a block of code with the following items: +/// +/// - `default`: The default value for the field. If this item is omitted, `Default::default()` is +/// used instead, meaning that the type of the field must implement `Default`. +/// - `methods`: A block of code containing methods for the `Builder` type. These methods should be +/// related to the field being declared. +/// - `as_args`: This item declares how the field should be converted into a valid CLI argument for +/// `bindgen` and is used in the [`Builder::command_line_flags`] method which is used to do a +/// roundtrip test of the CLI args in the `bindgen-test` crate. This item can take one of the +/// following: +/// - A string literal with the flag if the type of the field implements the [`AsArgs`] trait. +/// - A closure with the signature `|field, args: &mut Vec| -> ()` that pushes arguments +/// into the `args` buffer based on the value of the field. This is used if the field does not +/// implement `AsArgs` or if the implementation of the trait is not logically correct for the +/// option and a custom behavior must be taken into account. +/// - The `ignore` literal, which does not emit any CLI arguments for this field. This is useful +/// if the field cannot be used from the `bindgen` CLI. +/// +/// As an example, this would be the declaration of a `bool` field called `be_fun` whose default +/// value is `false` (the `Default` value for `bool`): +/// ```rust,ignore +/// be_fun: bool { +/// methods: { +/// /// Ask `bindgen` to be fun. This option is disabled by default. +/// fn be_fun(mut self) -> Self { +/// self.options.be_fun = true; +/// self +/// } +/// }, +/// as_args: "--be-fun", +/// } +/// ``` +/// +/// However, we could also set the `be_fun` field to `true` by default and use a `--not-fun` flag +/// instead. This means that we have to add the `default` item and use a closure in the `as_args` +/// item: +/// ```rust,ignore +/// be_fun: bool { +/// default: true, +/// methods: { +/// /// Ask `bindgen` to not be fun. `bindgen` is fun by default. +/// fn not_fun(mut self) -> Self { +/// self.options.be_fun = false; +/// self +/// } +/// }, +/// as_args: |be_fun, args| (!be_fun).as_args(args, "--not-fun"), +/// } +/// ``` +/// More complex examples can be found in the sole invocation of this macro. +macro_rules! options { + ($( + $(#[doc = $docs:literal])+ + $field:ident: $ty:ty { + $(default: $default:expr,)? + methods: {$($methods_tokens:tt)*}$(,)? + as_args: $as_args:expr$(,)? + }$(,)? + )*) => { + #[derive(Debug, Clone)] + pub(crate) struct BindgenOptions { + $($(#[doc = $docs])* pub(crate) $field: $ty,)* + } + + impl Default for BindgenOptions { + fn default() -> Self { + Self { + $($field: default!($($default)*),)* + } + } + } + + impl Builder { + /// Generates the command line flags used to create this [`Builder`]. + pub fn command_line_flags(&self) -> Vec { + let mut args = vec![]; + + let headers = match self.options.input_headers.split_last() { + Some((header, headers)) => { + // The last input header is passed as an argument in the first position. + args.push(header.clone().into()); + headers + }, + None => &[] + }; + + $({ + let func: fn(&$ty, &mut Vec) = as_args!($as_args); + func(&self.options.$field, &mut args); + })* + + // Add the `--experimental` flag if `bindgen` is built with the `experimental` + // feature. + if cfg!(feature = "experimental") { + args.push("--experimental".to_owned()); + } + + // Add all the clang arguments. + args.push("--".to_owned()); + + if !self.options.clang_args.is_empty() { + args.extend(self.options.clang_args.iter().map(|s| s.clone().into())); + } + + // We need to pass all but the last header via the `-include` clang argument. + for header in headers { + args.push("-include".to_owned()); + args.push(header.clone().into()); + } + + args + } + + $($($methods_tokens)*)* + } + }; +} + +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: { + regex_option! { + /// Do not generate any bindings for the given type. + /// + /// This option is not recursive, meaning that it will only block types whose names + /// explicitly match the argument of this method. + pub fn blocklist_type>(mut self, arg: T) -> Builder { + self.options.blocklisted_types.insert(arg); + self + } + } + }, + as_args: "--blocklist-type", + }, + /// Functions that have been blocklisted and should not appear in the generated code. + blocklisted_functions: RegexSet { + methods: { + regex_option! { + /// Do not generate any bindings for the given function. + /// + /// This option is not recursive, meaning that it will only block functions whose + /// names explicitly match the argument of this method. + pub fn blocklist_function>(mut self, arg: T) -> Builder { + self.options.blocklisted_functions.insert(arg); + self + } + } + }, + as_args: "--blocklist-function", + }, + /// Items that have been blocklisted and should not appear in the generated code. + blocklisted_items: RegexSet { + methods: { + regex_option! { + /// Do not generate any bindings for the given item, regardless of whether it is a + /// type, function, module, etc. + /// + /// This option is not recursive, meaning that it will only block items whose names + /// explicitly match the argument of this method. + pub fn blocklist_item>(mut self, arg: T) -> Builder { + self.options.blocklisted_items.insert(arg); + self + } + } + }, + as_args: "--blocklist-item", + }, + /// Files whose contents should be blocklisted and should not appear in the generated code. + blocklisted_files: RegexSet { + methods: { + regex_option! { + /// Do not generate any bindings for the contents of the given file, regardless of + /// whether the contents of the file are types, functions, modules, etc. + /// + /// This option is not recursive, meaning that it will only block files whose names + /// explicitly match the argument of this method. + /// + /// This method will use the argument to match the complete path of the file + /// instead of a section of it. + pub fn blocklist_file>(mut self, arg: T) -> Builder { + self.options.blocklisted_files.insert(arg); + self + } + } + }, + as_args: "--blocklist-file", + }, + /// Variables that have been blocklisted and should not appear in the generated code. + blocklisted_vars: RegexSet { + methods: { + regex_option! { + /// Do not generate any bindings for the given variable. + /// + /// This option is not recursive, meaning that it will only block variables whose + /// names explicitly match the argument of this method. + pub fn blocklist_var>(mut self, arg: T) -> Builder { + self.options.blocklisted_vars.insert(arg); + self + } + } + }, + as_args: "--blocklist-var", + }, + /// Types that should be treated as opaque structures in the generated code. + opaque_types: RegexSet { + methods: { + regex_option! { + /// Treat the given type as opaque in the generated bindings. + /// + /// Opaque in this context means that none of the generated bindings will contain + /// information about the inner representation of the type and the type itself will + /// be represented as a chunk of bytes with the alignment and size of the type. + pub fn opaque_type>(mut self, arg: T) -> Builder { + self.options.opaque_types.insert(arg); + self + } + } + }, + as_args: "--opaque-type", + }, + /// The explicit `rustfmt` path. + rustfmt_path: Option { + methods: { + /// Set an explicit path to the `rustfmt` binary. + /// + /// This option only comes into effect if `rustfmt` is set to be the formatter used by + /// `bindgen`. Check the documentation of the [`Builder::formatter`] method for more + /// information. + pub fn with_rustfmt>(mut self, path: P) -> Self { + self.options.rustfmt_path = Some(path.into()); + self + } + }, + // This option cannot be set from the CLI. + as_args: ignore, + }, + /// The path to which we should write a Makefile-syntax depfile (if any). + depfile: Option { + methods: { + /// Add a depfile output which will be written alongside the generated bindings. + pub fn depfile, D: Into>( + mut self, + output_module: H, + depfile: D, + ) -> Builder { + self.options.depfile = Some(DepfileSpec { + output_module: output_module.into(), + depfile_path: depfile.into(), + }); + self + } + }, + as_args: |depfile, args| { + if let Some(depfile) = depfile { + args.push("--depfile".into()); + args.push(depfile.depfile_path.display().to_string()); + } + }, + }, + /// Types that have been allowlisted and should appear in the generated code. + allowlisted_types: RegexSet { + methods: { + regex_option! { + /// Generate bindings for the given type. + /// + /// This option is transitive by default. Check the documentation of the + /// [`Builder::allowlist_recursively`] method for further information. + pub fn allowlist_type>(mut self, arg: T) -> Builder { + self.options.allowlisted_types.insert(arg); + self + } + } + }, + as_args: "--allowlist-type", + }, + /// Functions that have been allowlisted and should appear in the generated code. + allowlisted_functions: RegexSet { + methods: { + regex_option! { + /// Generate bindings for the given function. + /// + /// This option is transitive by default. Check the documentation of the + /// [`Builder::allowlist_recursively`] method for further information. + pub fn allowlist_function>(mut self, arg: T) -> Builder { + self.options.allowlisted_functions.insert(arg); + self + } + } + }, + as_args: "--allowlist-function", + }, + /// Variables that have been allowlisted and should appear in the generated code. + allowlisted_vars: RegexSet { + methods: { + regex_option! { + /// Generate bindings for the given variable. + /// + /// This option is transitive by default. Check the documentation of the + /// [`Builder::allowlist_recursively`] method for further information. + pub fn allowlist_var>(mut self, arg: T) -> Builder { + self.options.allowlisted_vars.insert(arg); + self + } + } + }, + as_args: "--allowlist-var", + }, + /// Files whose contents have been allowlisted and should appear in the generated code. + allowlisted_files: RegexSet { + methods: { + regex_option! { + /// Generate bindings for the content of the given file. + /// + /// This option is transitive by default. Check the documentation of the + /// [`Builder::allowlist_recursively`] method for further information. + /// + /// This method will use the argument to match the complete path of the file + /// instead of a section of it. + pub fn allowlist_file>(mut self, arg: T) -> Builder { + self.options.allowlisted_files.insert(arg); + self + } + } + }, + as_args: "--allowlist-file", + }, + /// Items that have been allowlisted and should appear in the generated code. + allowlisted_items: RegexSet { + methods: { + regex_option! { + /// Generate bindings for the given item, regardless of whether it is a type, + /// function, module, etc. + /// + /// This option is transitive by default. Check the documentation of the + /// [`Builder::allowlist_recursively`] method for further information. + pub fn allowlist_item>(mut self, arg: T) -> Builder { + self.options.allowlisted_items.insert(arg); + self + } + } + }, + as_args: "--allowlist-item", + }, + /// The default style of for generated `enum`s. + default_enum_style: EnumVariation { + methods: { + /// Set the default style for generated `enum`s. + /// + /// If this method is not called, the [`EnumVariation::Consts`] style will be used by + /// default. + /// + /// To set the style for individual `enum`s, use [`Builder::bitfield_enum`], + /// [`Builder::newtype_enum`], [`Builder::newtype_global_enum`], + /// [`Builder::rustified_enum`], [`Builder::rustified_non_exhaustive_enum`], + /// [`Builder::constified_enum_module`] or [`Builder::constified_enum`]. + pub fn default_enum_style( + mut self, + arg: EnumVariation, + ) -> Builder { + self.options.default_enum_style = arg; + self + } + }, + as_args: |variation, args| { + if *variation != Default::default() { + args.push("--default-enum-style".to_owned()); + args.push(variation.to_string()); + } + }, + }, + /// `enum`s marked as bitfield-like. This is, newtypes with bitwise operations. + bitfield_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as being bitfield-like. + /// + /// This is similar to the [`Builder::newtype_enum`] style, but with the bitwise + /// operators implemented. + pub fn bitfield_enum>(mut self, arg: T) -> Builder { + self.options.bitfield_enums.insert(arg); + self + } + } + }, + as_args: "--bitfield-enum", + }, + /// `enum`s marked as newtypes. + newtype_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a newtype. + /// + /// This means that an integer newtype will be declared to represent the `enum` + /// type and its variants will be represented as constants inside of this type's + /// `impl` block. + pub fn newtype_enum>(mut self, arg: T) -> Builder { + self.options.newtype_enums.insert(arg); + self + } + } + }, + as_args: "--newtype-enum", + }, + /// `enum`s marked as global newtypes . + newtype_global_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a global newtype. + /// + /// This is similar to the [`Builder::newtype_enum`] style, but the constants for + /// each variant are free constants instead of being declared inside an `impl` + /// block for the newtype. + pub fn newtype_global_enum>(mut self, arg: T) -> Builder { + self.options.newtype_global_enums.insert(arg); + self + } + } + }, + as_args: "--newtype-global-enum", + }, + /// `enum`s marked as Rust `enum`s. + rustified_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a Rust `enum`. + /// + /// This means that each variant of the `enum` will be represented as a Rust `enum` + /// variant. + /// + /// **Use this with caution**, creating an instance of a Rust `enum` with an + /// invalid value will cause undefined behaviour. To avoid this, use the + /// [`Builder::newtype_enum`] style instead. + pub fn rustified_enum>(mut self, arg: T) -> Builder { + self.options.rustified_enums.insert(arg); + self + } + } + }, + as_args: "--rustified-enum", + }, + /// `enum`s marked as non-exhaustive Rust `enum`s. + rustified_non_exhaustive_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a non-exhaustive Rust `enum`. + /// + /// 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-enum", + }, + /// `enum`s marked as modules of constants. + constified_enum_modules: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a module with a set of integer constants. + pub fn constified_enum_module>(mut self, arg: T) -> Builder { + self.options.constified_enum_modules.insert(arg); + self + } + } + }, + as_args: "--constified-enum-module", + }, + /// `enum`s marked as a set of constants. + constified_enums: RegexSet { + methods: { + regex_option! { + /// Mark the given `enum` as a set of integer constants. + /// + /// This is similar to the [`Builder::constified_enum_module`] style, but the + /// constants are generated in the current module instead of in a new module. + pub fn constified_enum>(mut self, arg: T) -> Builder { + self.options.constified_enums.insert(arg); + self + } + } + }, + as_args: "--constified-enum", + }, + /// The default type signedness for C macro constants. + default_macro_constant_type: MacroTypeVariation { + methods: { + /// Set the default type signedness to be used for macro constants. + /// + /// If this method is not called, [`MacroTypeVariation::Unsigned`] is used by default. + /// + /// To set the type for individual macro constants, use the + /// [`ParseCallbacks::int_macro`] method. + pub fn default_macro_constant_type(mut self, arg: MacroTypeVariation) -> Builder { + self.options.default_macro_constant_type = arg; + self + } + + }, + as_args: |variation, args| { + if *variation != Default::default() { + args.push("--default-macro-constant-type".to_owned()); + args.push(variation.to_string()); + } + }, + }, + /// The default style of code generation for `typedef`s. + default_alias_style: AliasVariation { + methods: { + /// Set the default style of code generation for `typedef`s. + /// + /// If this method is not called, the [`AliasVariation::TypeAlias`] style is used by + /// default. + /// + /// To set the style for individual `typedefs`s, use [`Builder::type_alias`], + /// [`Builder::new_type_alias`] or [`Builder::new_type_alias_deref`]. + pub fn default_alias_style( + mut self, + arg: AliasVariation, + ) -> Builder { + self.options.default_alias_style = arg; + self + } + }, + as_args: |variation, args| { + if *variation != Default::default() { + args.push("--default-alias-style".to_owned()); + args.push(variation.to_string()); + } + }, + }, + /// `typedef` patterns that will use regular type aliasing. + type_alias: RegexSet { + methods: { + regex_option! { + /// Mark the given `typedef` as a regular Rust `type` alias. + /// + /// This is the default behavior, meaning that this method only comes into effect + /// if a style different from [`AliasVariation::TypeAlias`] was passed to the + /// [`Builder::default_alias_style`] method. + pub fn type_alias>(mut self, arg: T) -> Builder { + self.options.type_alias.insert(arg); + self + } + } + }, + as_args: "--type-alias", + }, + /// `typedef` patterns that will be aliased by creating a newtype. + new_type_alias: RegexSet { + methods: { + regex_option! { + /// Mark the given `typedef` as a Rust newtype by having the aliased + /// type be wrapped in a `struct` with `#[repr(transparent)]`. + /// + /// This method can be used to enforce stricter type checking. + pub fn new_type_alias>(mut self, arg: T) -> Builder { + self.options.new_type_alias.insert(arg); + self + } + } + }, + as_args: "--new-type-alias", + }, + /// `typedef` patterns that will be wrapped in a newtype implementing `Deref` and `DerefMut`. + new_type_alias_deref: RegexSet { + methods: { + regex_option! { + /// Mark the given `typedef` to be generated as a newtype that can be dereferenced. + /// + /// This is similar to the [`Builder::new_type_alias`] style, but the newtype + /// implements `Deref` and `DerefMut` with the aliased type as a target. + pub fn new_type_alias_deref>(mut self, arg: T) -> Builder { + self.options.new_type_alias_deref.insert(arg); + self + } + } + }, + as_args: "--new-type-alias-deref", + }, + /// The default style of code to generate for `union`s containing non-`Copy` members. + default_non_copy_union_style: NonCopyUnionStyle { + methods: { + /// Set the default style of code to generate for `union`s with non-`Copy` members. + /// + /// If this method is not called, the [`NonCopyUnionStyle::BindgenWrapper`] style is + /// used by default. + /// + /// To set the style for individual `union`s, use [`Builder::bindgen_wrapper_union`] or + /// [`Builder::manually_drop_union`]. + pub fn default_non_copy_union_style(mut self, arg: NonCopyUnionStyle) -> Self { + self.options.default_non_copy_union_style = arg; + self + } + }, + as_args: |style, args| { + if *style != Default::default() { + args.push("--default-non-copy-union-style".to_owned()); + args.push(style.to_string()); + } + }, + }, + /// The patterns marking non-`Copy` `union`s as using the `bindgen` generated wrapper. + bindgen_wrapper_union: RegexSet { + methods: { + regex_option! { + /// Mark the given `union` to use a `bindgen`-generated wrapper for its members if at + /// least one them is not `Copy`. + /// + /// This is the default behavior, meaning that this method only comes into effect + /// if a style different from [`NonCopyUnionStyle::BindgenWrapper`] was passed to + /// the [`Builder::default_non_copy_union_style`] method. + pub fn bindgen_wrapper_union>(mut self, arg: T) -> Self { + self.options.bindgen_wrapper_union.insert(arg); + self + } + } + }, + as_args: "--bindgen-wrapper-union", + }, + /// The patterns marking non-`Copy` `union`s as using the `ManuallyDrop` wrapper. + manually_drop_union: RegexSet { + methods: { + regex_option! { + /// Mark the given `union` to use [`::core::mem::ManuallyDrop`] for its members if + /// at least one of them is not `Copy`. + /// + /// The `ManuallyDrop` type was stabilized in Rust 1.20.0, do not use this option + /// if your target version is lower than this. + pub fn manually_drop_union>(mut self, arg: T) -> Self { + self.options.manually_drop_union.insert(arg); + self + } + } + + }, + as_args: "--manually-drop-union", + }, + + + /// Whether we should generate built-in definitions. + builtins: bool { + methods: { + /// Generate Rust bindings for built-in definitions (for example `__builtin_va_list`). + /// + /// Bindings for built-in definitions are not emitted by default. + pub fn emit_builtins(mut self) -> Builder { + self.options.builtins = true; + self + } + }, + as_args: "--builtins", + }, + /// Whether we should dump the Clang AST for debugging purposes. + emit_ast: bool { + methods: { + /// Emit the Clang AST to `stdout` for debugging purposes. + /// + /// The Clang AST is not emitted by default. + pub fn emit_clang_ast(mut self) -> Builder { + self.options.emit_ast = true; + self + } + }, + as_args: "--emit-clang-ast", + }, + /// Whether we should dump our IR for debugging purposes. + emit_ir: bool { + methods: { + /// Emit the `bindgen` internal representation to `stdout` for debugging purposes. + /// + /// This internal representation is not emitted by default. + pub fn emit_ir(mut self) -> Builder { + self.options.emit_ir = true; + self + } + }, + as_args: "--emit-ir", + }, + /// Output path for the `graphviz` DOT file. + emit_ir_graphviz: Option { + methods: { + /// Set the path for the file where the`bindgen` internal representation will be + /// emitted as a graph using the `graphviz` DOT language. + /// + /// This graph representation is not emitted by default. + pub fn emit_ir_graphviz>(mut self, path: T) -> Builder { + let path = path.into(); + self.options.emit_ir_graphviz = Some(path); + self + } + }, + as_args: "--emit-ir-graphviz", + }, + + /// Whether we should emulate C++ namespaces with Rust modules. + enable_cxx_namespaces: bool { + methods: { + /// Emulate C++ namespaces using Rust modules in the generated bindings. + /// + /// C++ namespaces are not emulated by default. + pub fn enable_cxx_namespaces(mut self) -> Builder { + self.options.enable_cxx_namespaces = true; + self + } + }, + as_args: "--enable-cxx-namespaces", + }, + /// Whether we should try to find unexposed attributes in functions. + enable_function_attribute_detection: bool { + methods: { + /// Enable detecting function attributes on C functions. + /// + /// This enables the following features: + /// - Add `#[must_use]` attributes to Rust items whose C counterparts are marked as so. + /// This feature also requires that the Rust target version supports the attribute. + /// - Set `!` as the return type for Rust functions whose C counterparts are marked as + /// diverging. + /// + /// This option can be quite slow in some cases (check [#1465]), so it is disabled by + /// default. + /// + /// [#1465]: https://github.com/rust-lang/rust-bindgen/issues/1465 + pub fn enable_function_attribute_detection(mut self) -> Self { + self.options.enable_function_attribute_detection = true; + self + } + + }, + as_args: "--enable-function-attribute-detection", + }, + /// Whether we should avoid mangling names with namespaces. + disable_name_namespacing: bool { + methods: { + /// Disable name auto-namespacing. + /// + /// By default, `bindgen` mangles names like `foo::bar::Baz` to look like `foo_bar_Baz` + /// instead of just `Baz`. This method disables that behavior. + /// + /// Note that this does not change the names used for allowlisting and blocklisting, + /// which should still be mangled with the namespaces. Additionally, this option may + /// cause `bindgen` to generate duplicate names. + pub fn disable_name_namespacing(mut self) -> Builder { + self.options.disable_name_namespacing = true; + self + } + }, + as_args: "--disable-name-namespacing", + }, + /// Whether we should avoid generating nested `struct` names. + disable_nested_struct_naming: bool { + methods: { + /// Disable nested `struct` naming. + /// + /// The following `struct`s have different names for C and C++. In C, they are visible + /// as `foo` and `bar`. In C++, they are visible as `foo` and `foo::bar`. + /// + /// ```c + /// struct foo { + /// struct bar { + /// } b; + /// }; + /// ``` + /// + /// `bindgen` tries to avoid duplicate names by default, so it follows the C++ naming + /// convention and it generates `foo` and `foo_bar` instead of just `foo` and `bar`. + /// + /// This method disables this behavior and it is indented to be used only for headers + /// that were written in C. + pub fn disable_nested_struct_naming(mut self) -> Builder { + self.options.disable_nested_struct_naming = true; + self + } + }, + as_args: "--disable-nested-struct-naming", + }, + /// Whether we should avoid embedding version identifiers into source code. + disable_header_comment: bool { + methods: { + /// Do not insert the `bindgen` version identifier into the generated bindings. + /// + /// This identifier is inserted by default. + pub fn disable_header_comment(mut self) -> Self { + self.options.disable_header_comment = true; + self + } + + }, + as_args: "--disable-header-comment", + }, + /// Whether we should generate layout tests for generated `struct`s. + layout_tests: bool { + default: true, + methods: { + /// Set whether layout tests should be generated. + /// + /// Layout tests are generated by default. + pub fn layout_tests(mut self, doit: bool) -> Self { + self.options.layout_tests = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-layout-tests"), + }, + /// Whether we should implement `Debug` for types that cannot derive it. + impl_debug: bool { + methods: { + /// Set whether `Debug` should be implemented for types that cannot derive it. + /// + /// This option is disabled by default. + pub fn impl_debug(mut self, doit: bool) -> Self { + self.options.impl_debug = doit; + self + } + + }, + as_args: "--impl-debug", + }, + /// Whether we should implement `PartialEq` types that cannot derive it. + impl_partialeq: bool { + methods: { + /// Set whether `PartialEq` should be implemented for types that cannot derive it. + /// + /// This option is disabled by default. + pub fn impl_partialeq(mut self, doit: bool) -> Self { + self.options.impl_partialeq = doit; + self + } + }, + as_args: "--impl-partialeq", + }, + /// Whether we should derive `Copy` when possible. + derive_copy: bool { + default: true, + methods: { + /// Set whether the `Copy` trait should be derived when possible. + /// + /// `Copy` is derived by default. + pub fn derive_copy(mut self, doit: bool) -> Self { + self.options.derive_copy = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-derive-copy"), + }, + + /// Whether we should derive `Debug` when possible. + derive_debug: bool { + default: true, + methods: { + /// Set whether the `Debug` trait should be derived when possible. + /// + /// The [`Builder::impl_debug`] method can be used to implement `Debug` for types that + /// cannot derive it. + /// + /// `Debug` is derived by default. + pub fn derive_debug(mut self, doit: bool) -> Self { + self.options.derive_debug = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-derive-debug"), + }, + + /// Whether we should derive `Default` when possible. + derive_default: bool { + methods: { + /// Set whether the `Default` trait should be derived when possible. + /// + /// `Default` is not derived by default. + pub fn derive_default(mut self, doit: bool) -> Self { + self.options.derive_default = doit; + self + } + }, + as_args: |&value, args| { + let arg = if value { + "--with-derive-default" + } else { + "--no-derive-default" + }; + + args.push(arg.to_owned()); + }, + }, + /// Whether we should derive `Hash` when possible. + derive_hash: bool { + methods: { + /// Set whether the `Hash` trait should be derived when possible. + /// + /// `Hash` is not derived by default. + pub fn derive_hash(mut self, doit: bool) -> Self { + self.options.derive_hash = doit; + self + } + }, + as_args: "--with-derive-hash", + }, + /// Whether we should derive `PartialOrd` when possible. + derive_partialord: bool { + methods: { + /// Set whether the `PartialOrd` trait should be derived when possible. + /// + /// Take into account that `Ord` cannot be derived for a type that does not implement + /// `PartialOrd`. For this reason, setting this method to `false` also sets + /// automatically [`Builder::derive_ord`] to `false`. + /// + /// `PartialOrd` is not derived by default. + pub fn derive_partialord(mut self, doit: bool) -> Self { + self.options.derive_partialord = doit; + if !doit { + self.options.derive_ord = false; + } + self + } + }, + as_args: "--with-derive-partialord", + }, + /// Whether we should derive `Ord` when possible. + derive_ord: bool { + methods: { + /// Set whether the `Ord` trait should be derived when possible. + /// + /// Take into account that `Ord` cannot be derived for a type that does not implement + /// `PartialOrd`. For this reason, the value set with this method will also be set + /// automatically for [`Builder::derive_partialord`]. + /// + /// `Ord` is not derived by default. + pub fn derive_ord(mut self, doit: bool) -> Self { + self.options.derive_ord = doit; + self.options.derive_partialord = doit; + self + } + }, + as_args: "--with-derive-ord", + }, + /// Whether we should derive `PartialEq` when possible. + derive_partialeq: bool { + methods: { + /// Set whether the `PartialEq` trait should be derived when possible. + /// + /// Take into account that `Eq` cannot be derived for a type that does not implement + /// `PartialEq`. For this reason, setting this method to `false` also sets + /// automatically [`Builder::derive_eq`] to `false`. + /// + /// The [`Builder::impl_partialeq`] method can be used to implement `PartialEq` for + /// types that cannot derive it. + /// + /// `PartialEq` is not derived by default. + pub fn derive_partialeq(mut self, doit: bool) -> Self { + self.options.derive_partialeq = doit; + if !doit { + self.options.derive_eq = false; + } + self + } + }, + as_args: "--with-derive-partialeq", + }, + /// Whether we should derive `Eq` when possible. + derive_eq: bool { + methods: { + /// Set whether the `Eq` trait should be derived when possible. + /// + /// Take into account that `Eq` cannot be derived for a type that does not implement + /// `PartialEq`. For this reason, the value set with this method will also be set + /// automatically for [`Builder::derive_partialeq`]. + /// + /// `Eq` is not derived by default. + pub fn derive_eq(mut self, doit: bool) -> Self { + self.options.derive_eq = doit; + if doit { + self.options.derive_partialeq = doit; + } + self + } + }, + as_args: "--with-derive-eq", + }, + /// Whether we should use `core` instead of `std`. + /// + /// If this option is enabled and the Rust target version is greater than 1.64, the prefix for + /// C platform-specific types will be `::core::ffi` instead of `::core::os::raw`. + use_core: bool { + methods: { + /// Use `core` instead of `std` in the generated bindings. + /// + /// `std` is used by default. + pub fn use_core(mut self) -> Builder { + self.options.use_core = true; + self + } + + }, + as_args: "--use-core", + }, + /// An optional prefix for the C platform-specific types. + ctypes_prefix: Option { + methods: { + /// Use the given prefix for the C platform-specific types instead of `::std::os::raw`. + /// + /// Alternatively, the [`Builder::use_core`] method can be used to set the prefix to + /// `::core::ffi` or `::core::os::raw`. + pub fn ctypes_prefix>(mut self, prefix: T) -> Builder { + self.options.ctypes_prefix = Some(prefix.into()); + self + } + }, + as_args: "--ctypes-prefix", + }, + /// The prefix for anonymous fields. + anon_fields_prefix: String { + default: DEFAULT_ANON_FIELDS_PREFIX.into(), + methods: { + /// Use the given prefix for the anonymous fields. + /// + /// An anonymous field, is a field of a C/C++ type that does not have a name. For + /// example, in the following C code: + /// ```c + /// struct integer { + /// struct { + /// int inner; + /// }; + /// } + /// ``` + /// + /// The only field of the `integer` `struct` is an anonymous field and its Rust + /// representation will be named using this prefix followed by an integer identifier. + /// + /// The default prefix is `__bindgen_anon_`. + pub fn anon_fields_prefix>(mut self, prefix: T) -> Builder { + self.options.anon_fields_prefix = prefix.into(); + self + } + }, + as_args: |prefix, args| { + if prefix != DEFAULT_ANON_FIELDS_PREFIX { + args.push("--anon-fields-prefix".to_owned()); + args.push(prefix.clone()); + } + }, + }, + /// Whether to measure the time for each one of the `bindgen` phases. + time_phases: bool { + methods: { + /// Set whether to measure the elapsed time for each one of the `bindgen` phases. This + /// information is printed to `stderr`. + /// + /// The elapsed time is not measured by default. + pub fn time_phases(mut self, doit: bool) -> Self { + self.options.time_phases = doit; + self + } + }, + as_args: "--time-phases", + }, + /// Whether to convert C float types to `f32` and `f64`. + convert_floats: bool { + default: true, + methods: { + /// Avoid converting C float types to `f32` and `f64`. + pub fn no_convert_floats(mut self) -> Self { + self.options.convert_floats = false; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-convert-floats"), + }, + /// The set of raw lines to be prepended to the top-level module of the generated Rust code. + raw_lines: Vec> { + methods: { + /// Add a line of Rust code at the beginning of the generated bindings. The string is + /// passed through without any modification. + pub fn raw_line>(mut self, arg: T) -> Self { + self.options.raw_lines.push(arg.into().into_boxed_str()); + self + } + }, + as_args: |raw_lines, args| { + for line in raw_lines { + args.push("--raw-line".to_owned()); + args.push(line.clone().into()); + } + }, + }, + /// The set of raw lines to prepend to different modules. + module_lines: HashMap, Vec>> { + methods: { + /// Add a given line to the beginning of a given module. + /// + /// This option only comes into effect if the [`Builder::enable_cxx_namespaces`] method + /// is also being called. + pub fn module_raw_line(mut self, module: T, line: U) -> Self + where + T: Into, + U: Into, + { + self.options + .module_lines + .entry(module.into().into_boxed_str()) + .or_default() + .push(line.into().into_boxed_str()); + self + } + }, + as_args: |module_lines, args| { + for (module, lines) in module_lines { + for line in lines { + args.push("--module-raw-line".to_owned()); + args.push(module.clone().into()); + args.push(line.clone().into()); + } + } + }, + }, + /// The input header files. + input_headers: Vec> { + methods: { + /// Add an input C/C++ header to generate bindings for. + /// + /// This can be used to generate bindings for a single header: + /// + /// ```ignore + /// let bindings = bindgen::Builder::default() + /// .header("input.h") + /// .generate() + /// .unwrap(); + /// ``` + /// + /// Or for multiple headers: + /// + /// ```ignore + /// let bindings = bindgen::Builder::default() + /// .header("first.h") + /// .header("second.h") + /// .header("third.h") + /// .generate() + /// .unwrap(); + /// ``` + pub fn header>(mut self, header: T) -> Builder { + self.options.input_headers.push(header.into().into_boxed_str()); + self + } + + /// Add input C/C++ header(s) to generate bindings for. + /// + /// This can be used to generate bindings for a single header: + /// + /// ```ignore + /// let bindings = bindgen::Builder::default() + /// .headers(["input.h"]) + /// .generate() + /// .unwrap(); + /// ``` + /// + /// Or for multiple headers: + /// + /// ```ignore + /// let bindings = bindgen::Builder::default() + /// .headers(["first.h", "second.h", "third.h"]) + /// .generate() + /// .unwrap(); + /// ``` + pub fn headers(mut self, headers: I) -> Builder + where + I::Item: Into, + { + self.options + .input_headers + .extend(headers.into_iter().map(Into::into).map(Into::into)); + self + } + }, + // This field is handled specially inside the macro. + as_args: ignore, + }, + /// The set of arguments to be passed straight through to Clang. + clang_args: Vec> { + methods: { + /// Add an argument to be passed straight through to Clang. + pub fn clang_arg>(self, arg: T) -> Builder { + self.clang_args([arg.into().into_boxed_str()]) + } + + /// Add several arguments to be passed straight through to Clang. + pub fn clang_args(mut self, args: I) -> Builder + where + I::Item: AsRef, + { + for arg in args { + self.options.clang_args.push(arg.as_ref().to_owned().into_boxed_str()); + } + self + } + }, + // 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: { + /// Add `contents` as an input C/C++ header named `name`. + /// + /// This can be used to inject additional C/C++ code as an input without having to + /// create additional header files. + pub fn header_contents(mut self, name: &str, contents: &str) -> Builder { + // Apparently clang relies on having virtual FS correspondent to + // the real one, so we need absolute paths here + let absolute_path = env::current_dir() + .expect("Cannot retrieve current directory") + .join(name) + .to_str() + .expect("Cannot convert current directory name to string") + .into(); + self.options + .input_header_contents + .push((absolute_path, contents.into())); + self + } + }, + // Header contents cannot be added from the CLI. + as_args: ignore, + }, + /// A user-provided visitor to allow customizing different kinds of situations. + parse_callbacks: Vec> { + methods: { + /// Add a new [`ParseCallbacks`] instance to configure types in different situations. + /// + /// This can also be used with [`CargoCallbacks`](struct@crate::CargoCallbacks) to emit + /// `cargo:rerun-if-changed=...` for all `#include`d header files. + pub fn parse_callbacks(mut self, cb: Box) -> Self { + self.options.parse_callbacks.push(Rc::from(cb)); + self + } + }, + as_args: |_callbacks, _args| { + #[cfg(feature = "__cli")] + for cb in _callbacks { + _args.extend(cb.cli_args()); + } + }, + }, + /// Which kind of items should we generate. We generate all of them by default. + codegen_config: CodegenConfig { + default: CodegenConfig::all(), + methods: { + /// Do not generate any functions. + /// + /// Functions are generated by default. + pub fn ignore_functions(mut self) -> Builder { + self.options.codegen_config.remove(CodegenConfig::FUNCTIONS); + self + } + + /// Do not generate any methods. + /// + /// Methods are generated by default. + pub fn ignore_methods(mut self) -> Builder { + self.options.codegen_config.remove(CodegenConfig::METHODS); + self + } + + /// Choose what to generate using a [`CodegenConfig`]. + /// + /// This option overlaps with [`Builder::ignore_functions`] and + /// [`Builder::ignore_methods`]. + /// + /// All the items in `CodegenConfig` are generated by default. + pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self { + self.options.codegen_config = config; + self + } + }, + as_args: |codegen_config, args| { + if !codegen_config.functions() { + args.push("--ignore-functions".to_owned()); + } + + args.push("--generate".to_owned()); + + //Temporary placeholder for the 4 options below. + let mut options: Vec = Vec::new(); + if codegen_config.functions() { + options.push("functions".to_owned()); + } + + if codegen_config.types() { + options.push("types".to_owned()); + } + + if codegen_config.vars() { + options.push("vars".to_owned()); + } + + if codegen_config.methods() { + options.push("methods".to_owned()); + } + + if codegen_config.constructors() { + options.push("constructors".to_owned()); + } + + if codegen_config.destructors() { + options.push("destructors".to_owned()); + } + + args.push(options.join(",")); + + if !codegen_config.methods() { + args.push("--ignore-methods".to_owned()); + } + }, + }, + /// Whether to treat inline namespaces conservatively. + conservative_inline_namespaces: bool { + methods: { + /// Treat inline namespaces conservatively. + /// + /// This is tricky, because in C++ is technically legal to override an item + /// defined in an inline namespace: + /// + /// ```cpp + /// inline namespace foo { + /// using Bar = int; + /// } + /// using Bar = long; + /// ``` + /// + /// Even though referencing `Bar` is a compiler error. + /// + /// We want to support this (arguably esoteric) use case, but we do not want to make + /// the rest of `bindgen` users pay an usability penalty for that. + /// + /// To support this, we need to keep all the inline namespaces around, but then using + /// `bindgen` becomes a bit more difficult, because you cannot reference paths like + /// `std::string` (you'd need to use the proper inline namespace). + /// + /// We could complicate a lot of the logic to detect name collisions and, in the + /// absence of collisions, generate a `pub use inline_ns::*` or something like that. + /// + /// That is probably something we can do to improve the usability of this option if we + /// realize it is needed way more often. Our guess is that this extra logic is not + /// going to be very useful. + /// + /// This option is disabled by default. + pub fn conservative_inline_namespaces(mut self) -> Builder { + self.options.conservative_inline_namespaces = true; + self + } + }, + as_args: "--conservative-inline-namespaces", + }, + /// Whether to keep documentation comments in the generated output. + generate_comments: bool { + default: true, + methods: { + /// Set whether the generated bindings should contain documentation comments. + /// + /// Documentation comments are included by default. + /// + /// Note that clang excludes comments from system headers by default, pass + /// `"-fretain-comments-from-system-headers"` to the [`Builder::clang_arg`] method to + /// include them. + /// + /// It is also possible to process all comments and not just documentation using the + /// `"-fparse-all-comments"` flag. Check [these slides on clang comment parsing]( + /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for more information + /// and examples. + pub fn generate_comments(mut self, doit: bool) -> Self { + self.options.generate_comments = doit; + self + } + }, + 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: { + /// Set whether to generate inline functions. + /// + /// This option is disabled by default. + /// + /// 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. + /// + /// 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 + } + }, + as_args: "--generate-inline-functions", + }, + /// Whether to allowlist types recursively. + allowlist_recursively: bool { + default: true, + methods: { + /// Set whether to recursively allowlist items. + /// + /// Items are allowlisted recursively by default. + /// + /// Given that we have explicitly allowlisted the `initiate_dance_party` function in + /// this C header: + /// + /// ```c + /// typedef struct MoonBoots { + /// int bouncy_level; + /// } MoonBoots; + /// + /// void initiate_dance_party(MoonBoots* boots); + /// ``` + /// + /// We would normally generate bindings to both the `initiate_dance_party` function and + /// the `MoonBoots` type that it transitively references. If `false` is passed to this + /// method, `bindgen` will not emit bindings for anything except the explicitly + /// allowlisted items, meaning that the definition for `MoonBoots` would not be + /// generated. However, the `initiate_dance_party` function would still reference + /// `MoonBoots`! + /// + /// **Disabling this feature will almost certainly cause `bindgen` to emit bindings + /// that will not compile!** If you disable this feature, then it is *your* + /// responsibility to provide definitions for every type that is referenced from an + /// explicitly allowlisted item. One way to provide the missing definitions is by using + /// the [`Builder::raw_line`] method, another would be to define them in Rust and then + /// `include!(...)` the bindings immediately afterwards. + pub fn allowlist_recursively(mut self, doit: bool) -> Self { + self.options.allowlist_recursively = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-recursive-allowlist"), + }, + /// Whether to emit `#[macro_use] extern crate objc;` instead of `use objc;` in the prologue of + /// the files generated from objective-c files. + objc_extern_crate: bool { + methods: { + /// Emit `#[macro_use] extern crate objc;` instead of `use objc;` in the prologue of + /// the files generated from objective-c files. + /// + /// `use objc;` is emitted by default. + pub fn objc_extern_crate(mut self, doit: bool) -> Self { + self.options.objc_extern_crate = doit; + self + } + }, + as_args: "--objc-extern-crate", + }, + /// Whether to generate proper block signatures instead of `void` pointers. + generate_block: bool { + methods: { + /// Generate proper block signatures instead of `void` pointers. + /// + /// `void` pointers are used by default. + pub fn generate_block(mut self, doit: bool) -> Self { + self.options.generate_block = doit; + self + } + }, + as_args: "--generate-block", + }, + /// Whether to generate strings as `CStr`. + generate_cstr: bool { + methods: { + /// Set whether string constants should be generated as `&CStr` instead of `&[u8]`. + /// + /// A minimum Rust target of 1.59 is required for this to have any effect as support + /// for `CStr::from_bytes_with_nul_unchecked` in `const` contexts is needed. + /// + /// This option is disabled by default but will become enabled by default in a future + /// release, so enabling this is recommended. + pub fn generate_cstr(mut self, doit: bool) -> Self { + self.options.generate_cstr = doit; + self + } + }, + as_args: "--generate-cstr", + }, + /// Whether to emit `#[macro_use] extern crate block;` instead of `use block;` in the prologue + /// of the files generated from apple block files. + block_extern_crate: bool { + methods: { + /// Emit `#[macro_use] extern crate block;` instead of `use block;` in the prologue of + /// the files generated from apple block files. + /// + /// `use block;` is emitted by default. + pub fn block_extern_crate(mut self, doit: bool) -> Self { + self.options.block_extern_crate = doit; + self + } + }, + as_args: "--block-extern-crate", + }, + /// Whether to use the clang-provided name mangling. + enable_mangling: bool { + default: true, + methods: { + /// Set whether to use the clang-provided name mangling. This is probably needed for + /// C++ features. + /// + /// The mangling provided by clang is used by default. + /// + /// We allow disabling this option because some old `libclang` versions seem to return + /// incorrect results in some cases for non-mangled functions, check [#528] for more + /// information. + /// + /// [#528]: https://github.com/rust-lang/rust-bindgen/issues/528 + pub fn trust_clang_mangling(mut self, doit: bool) -> Self { + self.options.enable_mangling = doit; + self + } + + }, + as_args: |value, args| (!value).as_args(args, "--distrust-clang-mangling"), + }, + /// Whether to detect include paths using `clang_sys`. + detect_include_paths: bool { + default: true, + methods: { + /// Set whether to detect include paths using `clang_sys`. + /// + /// `clang_sys` is used to detect include paths by default. + pub fn detect_include_paths(mut self, doit: bool) -> Self { + self.options.detect_include_paths = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-include-path-detection"), + }, + /// Whether we should try to fit macro constants into types smaller than `u32` and `i32`. + fit_macro_constants: bool { + methods: { + /// Set whether `bindgen` should try to fit macro constants into types smaller than `u32` + /// and `i32`. + /// + /// This option is disabled by default. + pub fn fit_macro_constants(mut self, doit: bool) -> Self { + self.options.fit_macro_constants = doit; + self + } + }, + as_args: "--fit-macro-constant-types", + }, + /// Whether to prepend the `enum` name to constant or newtype variants. + prepend_enum_name: bool { + default: true, + methods: { + /// Set whether to prepend the `enum` name to constant or newtype variants. + /// + /// The `enum` name is prepended by default. + pub fn prepend_enum_name(mut self, doit: bool) -> Self { + self.options.prepend_enum_name = doit; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-prepend-enum-name"), + }, + /// Version of the Rust compiler to target. + rust_target: RustTarget { + methods: { + /// Specify the Rust target version. + /// + /// The default target is the latest stable Rust version. + pub fn rust_target(mut self, rust_target: RustTarget) -> Self { + self.options.set_rust_target(rust_target); + self + } + }, + as_args: |rust_target, args| { + args.push("--rust-target".to_owned()); + 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 { + methods: {}, + // This field cannot be set from the CLI, + as_args: ignore, + }, + /// Enable support for native Rust unions if they are supported. + untagged_union: bool { + default: true, + methods: { + /// Disable support for native Rust unions, if supported. + /// + /// The default value of this option is set based on the value passed to + /// [`Builder::rust_target`]. + pub fn disable_untagged_union(mut self) -> Self { + self.options.untagged_union = false; + self + } + } + as_args: |value, args| (!value).as_args(args, "--disable-untagged-union"), + }, + /// Whether we should record which items in the regex sets did match any C items. + record_matches: bool { + default: true, + methods: { + /// Set whether we should record which items in our regex sets did match any C items. + /// + /// Matches are recorded by default. + pub fn record_matches(mut self, doit: bool) -> Self { + self.options.record_matches = doit; + self + } + + }, + as_args: |value, args| (!value).as_args(args, "--no-record-matches"), + }, + /// Whether `size_t` should be translated to `usize` automatically. + size_t_is_usize: bool { + default: true, + methods: { + /// Set whether `size_t` should be translated to `usize`. + /// + /// If `size_t` is translated to `usize`, type definitions for `size_t` will not be + /// emitted. + /// + /// `size_t` is translated to `usize` by default. + pub fn size_t_is_usize(mut self, is: bool) -> Self { + self.options.size_t_is_usize = is; + self + } + }, + as_args: |value, args| (!value).as_args(args, "--no-size_t-is-usize"), + }, + /// The tool that should be used to format the generated bindings. + formatter: Formatter { + methods: { + /// Set whether `rustfmt` should be used to format the generated bindings. + /// + /// `rustfmt` is used by default. + /// + /// This method overlaps in functionality with the more general [`Builder::formatter`]. + /// Thus, the latter should be preferred. + #[deprecated] + pub fn rustfmt_bindings(mut self, doit: bool) -> Self { + self.options.formatter = if doit { + Formatter::Rustfmt + } else { + Formatter::None + }; + self + } + + /// Set which tool should be used to format the generated bindings. + /// + /// The default formatter is [`Formatter::Rustfmt`]. + /// + /// To be able to use `prettyplease` as a formatter, the `"prettyplease"` feature for + /// `bindgen` must be enabled in the Cargo manifest. + pub fn formatter(mut self, formatter: Formatter) -> Self { + self.options.formatter = formatter; + self + } + }, + as_args: |formatter, args| { + if *formatter != Default::default() { + args.push("--formatter".to_owned()); + args.push(formatter.to_string()); + } + }, + }, + /// The absolute path to the `rustfmt` configuration file. + rustfmt_configuration_file: Option { + methods: { + /// Set the absolute path to the `rustfmt` configuration file. + /// + /// The default `rustfmt` options are used if `None` is passed to this method or if + /// this method is not called at all. + /// + /// Calling this method will set the [`Builder::rustfmt_bindings`] option to `true` + /// and the [`Builder::formatter`] option to [`Formatter::Rustfmt`]. + pub fn rustfmt_configuration_file(mut self, path: Option) -> Self { + self = self.formatter(Formatter::Rustfmt); + self.options.rustfmt_configuration_file = path; + self + } + }, + as_args: "--rustfmt-configuration-file", + }, + /// Types that should not derive `PartialEq`. + no_partialeq_types: RegexSet { + methods: { + regex_option! { + /// Do not derive `PartialEq` for a given type. + pub fn no_partialeq>(mut self, arg: T) -> Builder { + self.options.no_partialeq_types.insert(arg.into()); + self + } + } + }, + as_args: "--no-partialeq", + }, + /// Types that should not derive `Copy`. + no_copy_types: RegexSet { + methods: { + regex_option! { + /// Do not derive `Copy` and `Clone` for a given type. + pub fn no_copy>(mut self, arg: T) -> Self { + self.options.no_copy_types.insert(arg.into()); + self + } + } + }, + as_args: "--no-copy", + }, + /// Types that should not derive `Debug`. + no_debug_types: RegexSet { + methods: { + regex_option! { + /// Do not derive `Debug` for a given type. + pub fn no_debug>(mut self, arg: T) -> Self { + self.options.no_debug_types.insert(arg.into()); + self + } + } + }, + as_args: "--no-debug", + }, + /// Types that should not derive or implement `Default`. + no_default_types: RegexSet { + methods: { + regex_option! { + /// Do not derive or implement `Default` for a given type. + pub fn no_default>(mut self, arg: T) -> Self { + self.options.no_default_types.insert(arg.into()); + self + } + } + }, + as_args: "--no-default", + }, + /// Types that should not derive `Hash`. + no_hash_types: RegexSet { + methods: { + regex_option! { + /// Do not derive `Hash` for a given type. + pub fn no_hash>(mut self, arg: T) -> Builder { + self.options.no_hash_types.insert(arg.into()); + self + } + } + }, + as_args: "--no-hash", + }, + /// Types that should be annotated with `#[must_use]`. + must_use_types: RegexSet { + methods: { + regex_option! { + /// Annotate the given type with the `#[must_use]` attribute. + pub fn must_use_type>(mut self, arg: T) -> Builder { + self.options.must_use_types.insert(arg.into()); + self + } + } + }, + as_args: "--must-use-type", + }, + /// Whether C arrays should be regular pointers in rust or array pointers + array_pointers_in_arguments: bool { + methods: { + /// Translate arrays `T arr[size]` into array pointers `*mut [T; size]` instead of + /// translating them as `*mut T` which is the default. + /// + /// The same is done for `*const` pointers. + pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { + self.options.array_pointers_in_arguments = doit; + self + } + + }, + 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: { + /// Adds the `#[link(wasm_import_module = import_name)]` attribute to all the `extern` + /// blocks generated by `bindgen`. + /// + /// This attribute is not added by default. + pub fn wasm_import_module_name>( + mut self, + import_name: T, + ) -> Self { + self.options.extern_fn_block_attrs.push(format!( + "#[link(wasm_import_module = \"{}\")]", import_name.into() + )); + self + } + }, + as_args: "--wasm-import-module-name", + }, + /// The name of the dynamic library (if we are generating bindings for a shared library). + dynamic_library_name: Option { + methods: { + /// Generate bindings for a shared library with the given name. + /// + /// This option is disabled by default. + pub fn dynamic_library_name>( + mut self, + dynamic_library_name: T, + ) -> Self { + self.options.dynamic_library_name = Some(dynamic_library_name.into()); + self + } + }, + as_args: "--dynamic-loading", + }, + /// Whether to require successful linkage for all routines in a shared library. + dynamic_link_require_all: bool { + methods: { + /// Set whether to require successful linkage for all routines in a shared library. + /// This allows us to optimize function calls by being able to safely assume function + /// pointers are valid. + /// + /// This option only comes into effect if the [`Builder::dynamic_library_name`] option + /// is set. + /// + /// This option is disabled by default. + pub fn dynamic_link_require_all(mut self, req: bool) -> Self { + self.options.dynamic_link_require_all = req; + self + } + }, + as_args: "--dynamic-link-require-all", + }, + /// Whether to only make generated bindings `pub` if the items would be publicly accessible by + /// C++. + respect_cxx_access_specs: bool { + methods: { + /// Set whether to respect the C++ access specifications. + /// + /// Passing `true` to this method will set the visibility of the generated Rust items + /// as `pub` only if the corresponding C++ items are publicly accessible instead of + /// marking all the items as public, which is the default. + pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self { + self.options.respect_cxx_access_specs = doit; + self + } + + }, + as_args: "--respect-cxx-access-specs", + }, + /// Whether to translate `enum` integer types to native Rust integer types. + translate_enum_integer_types: bool { + methods: { + /// Set whether to always translate `enum` integer types to native Rust integer types. + /// + /// Passing `true` to this method will result in `enum`s having types such as `u32` and + /// `i16` instead of `c_uint` and `c_short` which is the default. The `#[repr]` types + /// of Rust `enum`s are always translated to Rust integer types. + pub fn translate_enum_integer_types(mut self, doit: bool) -> Self { + self.options.translate_enum_integer_types = doit; + self + } + }, + as_args: "--translate-enum-integer-types", + }, + /// Whether to generate types with C style naming. + c_naming: bool { + methods: { + /// Set whether to generate types with C style naming. + /// + /// Passing `true` to this method will add prefixes to the generated type names. For + /// example, instead of a `struct` with name `A` we will generate a `struct` with + /// `struct_A`. Currently applies to `struct`s, `union`s, and `enum`s. + pub fn c_naming(mut self, doit: bool) -> Self { + self.options.c_naming = doit; + self + } + }, + as_args: "--c-naming", + }, + /// Whether to always emit explicit padding fields. + force_explicit_padding: bool { + methods: { + /// Set whether to always emit explicit padding fields. + /// + /// This option should be enabled if a `struct` needs to be serialized in its native + /// format (padding bytes and all). This could be required if such `struct` will be + /// written to a file or sent over the network, as anything reading the padding bytes + /// of a struct may cause undefined behavior. + /// + /// Padding fields are not emitted by default. + pub fn explicit_padding(mut self, doit: bool) -> Self { + self.options.force_explicit_padding = doit; + self + } + }, + as_args: "--explicit-padding", + }, + /// Whether to emit vtable functions. + vtable_generation: bool { + methods: { + /// Set whether to enable experimental support to generate virtual table functions. + /// + /// This option should mostly work, though some edge cases are likely to be broken. + /// + /// Virtual table generation is disabled by default. + pub fn vtable_generation(mut self, doit: bool) -> Self { + self.options.vtable_generation = doit; + self + } + }, + as_args: "--vtable-generation", + }, + /// Whether to sort the generated Rust items. + sort_semantically: bool { + methods: { + /// Set whether to sort the generated Rust items in a predefined manner. + /// + /// Items are not ordered by default. + pub fn sort_semantically(mut self, doit: bool) -> Self { + self.options.sort_semantically = doit; + self + } + }, + as_args: "--sort-semantically", + }, + /// Whether to deduplicate `extern` blocks. + merge_extern_blocks: bool { + methods: { + /// Merge all extern blocks under the same module into a single one. + /// + /// Extern blocks are not merged by default. + pub fn merge_extern_blocks(mut self, doit: bool) -> Self { + self.options.merge_extern_blocks = doit; + self + } + }, + as_args: "--merge-extern-blocks", + }, + /// Whether to wrap unsafe operations in unsafe blocks. + wrap_unsafe_ops: bool { + methods: { + /// Wrap all unsafe operations in unsafe blocks. + /// + /// Unsafe operations are not wrapped by default. + pub fn wrap_unsafe_ops(mut self, doit: bool) -> Self { + self.options.wrap_unsafe_ops = doit; + self + } + }, + as_args: "--wrap-unsafe-ops", + }, + /// Use DSTs to represent structures with flexible array members. + flexarray_dst: bool { + methods: { + /// Use DSTs to represent structures with flexible array members. + /// + /// This option is disabled by default. + pub fn flexarray_dst(mut self, doit: bool) -> Self { + self.options.flexarray_dst = doit; + self + } + }, + as_args: "--flexarray-dst", + }, + /// Patterns for functions whose ABI should be overridden. + abi_overrides: HashMap { + methods: { + regex_option! { + /// Override the ABI of a given function. + pub fn override_abi>(mut self, abi: Abi, arg: T) -> Self { + self.options + .abi_overrides + .entry(abi) + .or_default() + .insert(arg.into()); + self + } + } + }, + as_args: |overrides, args| { + for (abi, set) in overrides { + for item in set.get_items() { + args.push("--override-abi".to_owned()); + args.push(format!("{item}={abi}")); + } + } + }, + }, + /// Whether to generate wrappers for `static` functions. + wrap_static_fns: bool { + methods: { + /// 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 + /// called from Rust once the source file is compiled. + /// + /// The path of this source file can be set using the [`Builder::wrap_static_fns_path`] + /// method. + pub fn wrap_static_fns(mut self, doit: bool) -> Self { + self.options.wrap_static_fns = doit; + self + } + }, + as_args: "--wrap-static-fns", + }, + /// The suffix to be added to the function wrappers for `static` functions. + wrap_static_fns_suffix: Option { + methods: { + /// Set the suffix added to the wrappers for `static` functions. + /// + /// This option only comes into effect if `true` is passed to the + /// [`Builder::wrap_static_fns`] method. + /// + /// The default suffix is `__extern`. + pub fn wrap_static_fns_suffix>(mut self, suffix: T) -> Self { + self.options.wrap_static_fns_suffix = Some(suffix.as_ref().to_owned()); + self + } + }, + as_args: "--wrap-static-fns-suffix", + }, + /// The path of the file where the wrappers for `static` functions will be emitted. + wrap_static_fns_path: Option { + methods: { + /// 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. + /// + /// `bindgen` will automatically add the right extension to the header and source code + /// files. + /// + /// This option only comes into effect if `true` is passed to the + /// [`Builder::wrap_static_fns`] method. + /// + /// The default path is `temp_dir/bindgen/extern`, where `temp_dir` is the path + /// returned by [`std::env::temp_dir`] . + pub fn wrap_static_fns_path>(mut self, path: T) -> Self { + self.options.wrap_static_fns_path = Some(path.as_ref().to_owned()); + self + } + }, + as_args: "--wrap-static-fns-path", + }, + /// Default visibility of fields. + default_visibility: FieldVisibilityKind { + methods: { + /// Set the default visibility of fields, including bitfields and accessor methods for + /// bitfields. + /// + /// This option only comes into effect if the [`Builder::respect_cxx_access_specs`] + /// option is disabled. + pub fn default_visibility( + mut self, + visibility: FieldVisibilityKind, + ) -> Self { + self.options.default_visibility = visibility; + self + } + }, + as_args: |visibility, args| { + if *visibility != Default::default() { + args.push("--default-visibility".to_owned()); + args.push(visibility.to_string()); + } + }, + }, + /// Whether to emit diagnostics or not. + emit_diagnostics: bool { + methods: { + #[cfg(feature = "experimental")] + /// Emit diagnostics. + /// + /// These diagnostics are emitted to `stderr` if you are using `bindgen-cli` or printed + /// using `cargo:warning=` if you are using `bindgen` as a `build-dependency`. + /// + /// Diagnostics are not emitted by default. + /// + /// The layout and contents of these diagnostic messages are not covered by versioning + /// and can change without notice. + pub fn emit_diagnostics(mut self) -> Self { + self.options.emit_diagnostics = true; + self + } + }, + as_args: "--emit-diagnostics", + }, + /// Whether to use Clang evaluation on temporary files as a fallback for macros that fail to + /// parse. + clang_macro_fallback: bool { + methods: { + /// Use Clang as a fallback for macros that fail to parse using `CExpr`. + /// + /// This uses a workaround to evaluate each macro in a temporary file. Because this + /// results in slower compilation, this option is opt-in. + pub fn clang_macro_fallback(mut self) -> Self { + self.options.clang_macro_fallback = true; + self + } + }, + as_args: "--clang-macro-fallback", + } + /// Path to use for temporary files created by clang macro fallback code like precompiled + /// headers. + clang_macro_fallback_build_dir: Option { + methods: { + /// Set a path to a directory to which `.c` and `.h.pch` files should be written for the + /// purpose of using clang to evaluate macros that can't be easily parsed. + /// + /// The default location for `.h.pch` files is the directory that the corresponding + /// `.h` file is located in. The default for the temporary `.c` file used for clang + /// parsing is the current working directory. Both of these defaults are overridden + /// by this option. + pub fn clang_macro_fallback_build_dir>(mut self, path: P) -> Self { + self.options.clang_macro_fallback_build_dir = Some(path.as_ref().to_owned()); + self + } + }, + 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/parse.rs b/bindgen/parse.rs new file mode 100644 index 0000000000..d29b090fcb --- /dev/null +++ b/bindgen/parse.rs @@ -0,0 +1,41 @@ +//! Common traits and types related to parsing our IR from Clang cursors. +#![deny(clippy::missing_docs_in_private_items)] + +use crate::clang; +use crate::ir::context::{BindgenContext, ItemId}; + +/// Not so much an error in the traditional sense, but a control flow message +/// when walking over Clang's AST with a cursor. +#[derive(Debug)] +pub(crate) enum ParseError { + /// Recurse down the current AST node's children. + Recurse, + /// Continue on to the next sibling AST node, or back up to the parent's + /// siblings if we've exhausted all of this node's siblings (and so on). + Continue, +} + +/// The result of parsing a Clang AST node. +#[derive(Debug)] +pub(crate) enum ParseResult { + /// We've already resolved this item before, here is the extant `ItemId` for + /// it. + AlreadyResolved(ItemId), + + /// This is a newly parsed item. If the cursor is `Some`, it points to the + /// AST node where the new `T` was declared. + New(T, Option), +} + +/// An intermediate representation "sub-item" (i.e. one of the types contained +/// inside an `ItemKind` variant) that can be parsed from a Clang cursor. +pub(crate) trait ClangSubItemParser: Sized { + /// Attempt to parse this type from the given cursor. + /// + /// The fact that is a reference guarantees it's held by the context, and + /// allow returning already existing types. + fn parse( + cursor: clang::Cursor, + context: &mut BindgenContext, + ) -> Result, ParseError>; +} diff --git a/bindgen/regex_set.rs b/bindgen/regex_set.rs new file mode 100644 index 0000000000..32279557b5 --- /dev/null +++ b/bindgen/regex_set.rs @@ -0,0 +1,199 @@ +//! A type that represents the union of a set of regular expressions. +#![deny(clippy::missing_docs_in_private_items)] + +use regex::RegexSet as RxSet; +use std::cell::Cell; + +/// A dynamic set of regular expressions. +#[derive(Clone, Debug, Default)] +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`. + matched: Vec>, + set: Option, + /// Whether we should record matching items in the `matched` vector or not. + record_matches: bool, +} + +impl RegexSet { + /// Is this set empty? + pub(crate) fn is_empty(&self) -> bool { + self.items.is_empty() + } + + /// Insert a new regex into this set. + pub(crate) fn insert(&mut self, string: S) + where + S: AsRef, + { + self.items.push(string.as_ref().to_owned().into_boxed_str()); + self.matched.push(Cell::new(false)); + self.set = None; + } + + /// Returns slice of String from its field 'items' + 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(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; + } + + Some(item.as_ref()) + }) + } + + /// Construct a `RegexSet` from the set of entries we've accumulated. + /// + /// Must be called before calling `matches()`, or it will always return + /// false. + #[inline] + #[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 + /// name of the regex set is passed to it. + /// + /// Must be called before calling `matches()`, or it will always return + /// false. + #[inline] + pub(crate) fn build_with_diagnostics( + &mut self, + record_matches: bool, + name: Option<&'static str>, + ) { + self.build_inner(record_matches, name); + } + + #[cfg(all(not(feature = "__cli"), feature = "experimental"))] + /// 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(crate) fn build_with_diagnostics( + &mut self, + record_matches: bool, + name: Option<&'static str>, + ) { + self.build_inner(record_matches, name); + } + + fn build_inner( + &mut self, + record_matches: bool, + _name: Option<&'static str>, + ) { + 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 {:?}: {e:?}", self.items); + #[cfg(feature = "experimental")] + if let Some(name) = _name { + invalid_regex_warning(self, e, name); + } + None + } + } + } + + /// Does the given `string` match any of the regexes in this set? + pub(crate) fn matches(&self, string: S) -> bool + where + S: AsRef, + { + let s = string.as_ref(); + let Some(ref set) = self.set else { + return false; + }; + + if !self.record_matches { + return set.is_match(s); + } + + let matches = set.matches(s); + if !matches.matched_any() { + return false; + } + for i in &matches { + self.matched[i].set(true); + } + + true + } +} + +#[cfg(feature = "experimental")] +fn invalid_regex_warning( + set: &RegexSet, + err: regex::Error, + name: &'static str, +) { + use crate::diagnostics::{Diagnostic, Level, Slice}; + + let mut diagnostic = Diagnostic::default(); + + match err { + regex::Error::Syntax(string) => { + if string.starts_with("regex parse error:\n") { + let mut source = String::new(); + + let mut parsing_source = true; + + for line in string.lines().skip(1) { + if parsing_source { + if line.starts_with(' ') { + source.push_str(line); + source.push('\n'); + continue; + } + parsing_source = false; + } + let error = "error: "; + if line.starts_with(error) { + let (_, msg) = line.split_at(error.len()); + diagnostic.add_annotation(msg.to_owned(), Level::Error); + } else { + diagnostic.add_annotation(line.to_owned(), Level::Info); + } + } + let mut slice = Slice::default(); + slice.with_source(source); + diagnostic.add_slice(slice); + + diagnostic.with_title( + "Error while parsing a regular expression.", + Level::Warning, + ); + } else { + diagnostic.with_title(string, Level::Warning); + } + } + err => { + let err = err.to_string(); + diagnostic.with_title(err, Level::Warning); + } + } + + diagnostic.add_annotation( + format!("This regular expression was passed via `{name}`."), + Level::Note, + ); + + if set.items.iter().any(|item| item.as_ref() == "*") { + diagnostic.add_annotation("Wildcard patterns \"*\" are no longer considered valid. Use \".*\" instead.", Level::Help); + } + diagnostic.display(); +} diff --git a/src/time.rs b/bindgen/time.rs similarity index 85% rename from src/time.rs rename to bindgen/time.rs index c13a640c46..2952e36f76 100644 --- a/src/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/book.toml b/book/book.toml index 340134a32e..3f55b78377 100644 --- a/book/book.toml +++ b/book/book.toml @@ -1,4 +1,8 @@ [book] -title = "The `bindgen` User Guide" -author = "The Servo project developers" +title = "The bindgen User Guide" description = "`bindgen` automatically generates Rust FFI bindings to C and C++ libraries." + +[output.html] +git-repository-url = "https://github.com/rust-lang/rust-bindgen" +edit-url-template = "https://github.com/rust-lang/rust-bindgen/edit/main/book/{path}" +search.use-boolean-and = true diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index f9cc869f12..ac57aaad64 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,8 +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) - [Command Line Usage](./command-line-usage.md) - [Customizing the Generated Bindings](./customizing-generated-bindings.md) - [Allowlisting](./allowlisting.md) @@ -19,9 +20,12 @@ - [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) + - [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) - [FAQ](./faq.md) diff --git a/book/src/allowlisting.md b/book/src/allowlisting.md index edf93df0ef..99dd169865 100644 --- a/book/src/allowlisting.md +++ b/book/src/allowlisting.md @@ -20,6 +20,7 @@ transitively used by a definition that matches them. * [`bindgen::Builder::allowlist_function`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_function) * [`bindgen::Builder::allowlist_var`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_var) * [`bindgen::Builder::allowlist_file`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_file) +* [`bindgen::Builder::allowlist_item`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_item) ### Command Line @@ -27,6 +28,7 @@ transitively used by a definition that matches them. * `--allowlist-function ` * `--allowlist-var ` * `--allowlist-file ` +* `--allowlist-item ` ### Annotations diff --git a/book/src/blocklisting.md b/book/src/blocklisting.md index 6eb5786328..535a08c8d5 100644 --- a/book/src/blocklisting.md +++ b/book/src/blocklisting.md @@ -22,6 +22,7 @@ that are transitively included. * [`bindgen::Builder::blocklist_function`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_function) * [`bindgen::Builder::blocklist_item`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_item) * [`bindgen::Builder::blocklist_type`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_type) +* [`bindgen::Builder::blocklist_var`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_var) ### Command Line @@ -29,6 +30,7 @@ that are transitively included. * `--blocklist-function ` * `--blocklist-item ` * `--blocklist-type ` +* `--blocklist-var ` ### Annotations diff --git a/book/src/code-formatting.md b/book/src/code-formatting.md new file mode 100644 index 0000000000..368535c452 --- /dev/null +++ b/book/src/code-formatting.md @@ -0,0 +1,103 @@ +# Code Formatting + +`bindgen` uses `rustfmt` to format the emitted bindings. This section describes +how to adjust the `rustfmt` behavior when being used from `bindgen`. + +## Passing a `rustfmt.toml` configuration file + +`rustfmt` should automatically use any `rustfmt.toml` file that is present in +the directory from where `bindgen` will be run. If you want to use a +configuration file that has a different name or that is in a different +directory you can use the `--rustfmt-configuration-file` flag or the +[`Builder::rustfmt_configuration_file`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.rustfmt_configuration_file) +method. + +## Using a nightly release of `rustfmt` + +If the `rustfmt` command does not correspond to a nightly release of `rustfmt` +but you have `rustup` available, you can use `nightly` by following these +steps: + +### When using `bindgen` as a CLI application + +Use `rustup run` to run `bindgen`: + +```bash +$ rustup run nightly bindgen [ARGS] +``` + +### When using `bindgen` as a library + +Take the output of the following command: +```bash +$ rustup which rustfmt --toolchain=nightly +``` +and pass it to +[`Builder::with_rustfmt`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.with_rustfmt): + +```rust,ignore +use bindgen::Builder; +use std::process::Command; + +fn main() { + let output = Command::new("rustup") + .args(["which", "rustfmt", "--toolchain", "nightly"]) + .output() + .expect("Could not spawn `rustup` command"); + + assert!( + output.status.success(), + "Unsuccessful status code when running `rustup`: {output:?}", + ); + + let rustfmt_path = + String::from_utf8(output.stdout).expect("The `rustfmt` path is not valid `utf-8`"); + + let bindings = Builder::default() + .header("path/to/input.h") + .with_rustfmt(rustfmt_path) + .generate() + .expect("Could not generate bindings"); + + bindings + .write_to_file("path/to/output.rs") + .expect("Could not write bindings"); +} +``` + +These two methods also apply to any other toolchain available in your system. + +## Using `prettyplease` + +The [`prettyplease`](https://github.com/dtolnay/prettyplease) crate is a +minimal formatter for generated code. To format bindings using `prettyplease` +you have to invoke `bindgen` with either the `--formatter=prettyplease` flag or +the `bindgen::Builder::formatter(bindgen::Formatter::Prettyplease)`. One of +its advantages is that `prettyplease` can be used in minimal environments where +the Rust toolchain is not installed. + +## How can I normalize `#[doc]` attributes? + +`bindgen` emits all the documentation using `#[doc]` attributes by default. If +you want to use the more user-friendly `///` syntax, you have two options: + +### Use `rustfmt` + +`rustfmt` can be configured to normalize documentation. To do so, you have to +create a `rustfmt.toml` file with the following contents: + +```toml +normalize_doc_attributes = true +``` + +Then, you have set up `bindgen` so it passes this file to `rustfmt`. Given that +the `normalize_doc_attributes` option is +[unstable](https://github.com/rust-lang/rustfmt/issues/3351), you also have to +set up bindgen to use a `nightly` release of `rustfmt`. + + +### Use `prettyplease` + +`prettyplease` normalizes documentation without any additional configuration. +Then you just have to tell `bindgen` to use `prettyplease` as the code +formatter. diff --git a/book/src/command-line-usage.md b/book/src/command-line-usage.md index d90eb442b8..051a63efad 100644 --- a/book/src/command-line-usage.md +++ b/book/src/command-line-usage.md @@ -3,7 +3,7 @@ Install the `bindgen` executable with `cargo`: ```bash -$ cargo install bindgen +$ cargo install bindgen-cli ``` The `bindgen` executable is installed to `~/.cargo/bin`. You have to add that @@ -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 75ef855494..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. @@ -72,7 +72,88 @@ cannot translate into Rust: [the tracking issue for exceptions](https://github.com/rust-lang/rust-bindgen/issues/1208) for more details. -* Return value optimization. C++ compilers will in certain circumstances optimize functions - returning a struct type value to instead take an extra hidden argument that refers - to the return value struct. `bindgen` cannot necessarily know about this optimization and - thus at present `bindgen`-interfaces for these kinds of functions are invalid. +* Many C++ specific aspects of calling conventions. For example in the Itanium abi types that are + "[non trivial for the purposes of calls](https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial)" + should be passed by pointer, even if they are otherwise eligible to be passed in a register. + Similarly in both the Itanium and MSVC ABIs such types are returned by "hidden parameter", much like + large structs in C that would not fit into a register. This also applies to types with any base classes + in the MSVC ABI (see [x64 calling convention](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#return-values)). + Because bindgen does not know about these rules generated interfaces using such types are currently invalid. + +## Constructor semantics + +`bindgen` will generate a wrapper for any class constructor declared in the +input headers. For example, this headers file + +```c++ +class MyClass { + public: + MyClass(); + void method(); +}; +``` + +Will produce the following code: +```rust,ignore +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct MyClass { + pub _address: u8, +} +extern "C" { + #[link_name = "\u{1}_ZN7MyClass6methodEv"] + pub fn MyClass_method(this: *mut MyClass); +} +extern "C" { + #[link_name = "\u{1}_ZN7MyClassC1Ev"] + pub fn MyClass_MyClass(this: *mut MyClass); +} +impl MyClass { + #[inline] + pub unsafe fn method(&mut self) { + MyClass_method(self) + } + #[inline] + pub unsafe fn new() -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + MyClass_MyClass(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() + } +} +``` +This `MyClass::new` Rust method can be used as a substitute for the `MyClass` +C++ constructor. However, the address of the value from inside the method will +be different than from the outside. This is because the `__bindgen_tmp` value +is moved when the `MyClass::new` method returns. + +In contrast, the C++ constructor will not move the value, meaning that the +address of the value will be the same inside and outside the constructor. +If the original C++ relies on this semantic difference somehow, you should use the +`MyClass_MyClass` binding directly instead of the `MyClass::new` method. + +In other words, the Rust equivalent for the following C++ code + +```c++ +MyClass instance = MyClass(); +instance.method(); +``` + +is not this + +```rust,ignore +let instance = MyClass::new(); +instance.method(); +``` + +but this + +```rust,ignore +let instance = std::mem::MaybeUninit::::uninit(); +MyClass_MyClass(instance.as_mut_ptr()); +instance.assume_init_mut().method(); +``` + +You can easily verify this fact if you provide a implementation for `MyClass` +and `method` that prints the `this` pointer address. However, you can +ignore this fact if you know that the original C++ code does not rely on the +instance address in its internal logic. diff --git a/book/src/faq.md b/book/src/faq.md index 7a13afb4cd..59699ac757 100644 --- a/book/src/faq.md +++ b/book/src/faq.md @@ -7,6 +7,8 @@ - [Why isn't `bindgen` generating bindings to inline functions?](#why-isnt-bindgen-generating-bindings-to-inline-functions) - [Does `bindgen` support the C++ Standard Template Library (STL)?](#does-bindgen-support-the-c-standard-template-library-stl) - [How to deal with bindgen generated padding fields?](#how-to-deal-with-bindgen-generated-padding-fields) +- [How to generate bindings for a custom target?](#how-to-generate-bindings-for-a-custom-target) +- [Why isn't `bindgen` generating documentation for system headers?](#why-isnt-bindgen-generating-documentation-for-system-headers) @@ -45,13 +47,20 @@ 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`](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)? Sort of. A little. Depends what you mean by "support". @@ -68,12 +77,12 @@ you're binding to that is pulling in STL headers. ### How to deal with bindgen generated padding fields? Depending the architecture, toolchain versions and source struct, it is -possible that bindgen will generate padding fields named `__bindgen_padding_N`. +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 { @@ -95,3 +104,21 @@ SRC_DATA { In the case bindgen generates a padding field, then this field will 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`](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: +```bash +$ bindgen -- --target=armv7a-none-eabi +``` +If you are using `bindgen` as a library, you should call +`builder.clang_arg("--target=armv7a-none-eabi")` on your `builder`. + +### Why isn't `bindgen` generating documentation for system headers? + +By default, Bindgen does not generate documentation for system headers because +`libclang` does not provide this information. To address this, you should call +`builder.clang_arg("-fretain-comments-from-system-headers")` on your `builder`. 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 new file mode 100644 index 0000000000..598889d360 --- /dev/null +++ b/book/src/non-system-libraries.md @@ -0,0 +1,99 @@ +Now let's suppose we want to generate bindings for a non-system library. We +will be the same crate setup as the previous tutorial. First let's create a new +directory `hello` with two files inside it. A C source file `hello.c` +containing +```c +int hello() { + return 42; +} +``` +and a C header file `hello.h` containing +```c +int hello(); +``` + +Given that the library has not been compiled yet, we need to modify the +`build.rs` build script to compile the `hello.c` source file into a static +library: + +```rust,ignore +use std::env; +use std::path::PathBuf; + +fn main() { + // This is the directory where the `c` library is located. + let libdir_path = PathBuf::from("hello") + // Canonicalize the path as `rustc-link-search` requires an absolute + // path. + .canonicalize() + .expect("cannot canonicalize path"); + + // This is the path to the `c` headers file. + let headers_path = libdir_path.join("hello.h"); + let headers_path_str = headers_path.to_str().expect("Path is not a valid string"); + + // This is the path to the intermediate object file for our library. + let obj_path = libdir_path.join("hello.o"); + // This is the path to the static library file. + let lib_path = libdir_path.join("libhello.a"); + + // Tell cargo to look for shared libraries in the specified directory + println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap()); + + // Tell cargo to tell rustc to link our `hello` library. Cargo will + // automatically know it must look for a `libhello.a` file. + println!("cargo:rustc-link-lib=hello"); + + // Run `clang` to compile the `hello.c` file into a `hello.o` object file. + // Unwrap if it is not possible to spawn the process. + if !std::process::Command::new("clang") + .arg("-c") + .arg("-o") + .arg(&obj_path) + .arg(libdir_path.join("hello.c")) + .output() + .expect("could not spawn `clang`") + .status + .success() + { + // Panic if the command was not successful. + panic!("could not compile object file"); + } + + // Run `ar` to generate the `libhello.a` file from the `hello.o` file. + // Unwrap if it is not possible to spawn the process. + if !std::process::Command::new("ar") + .arg("rcs") + .arg(lib_path) + .arg(obj_path) + .output() + .expect("could not spawn `ar`") + .status + .success() + { + // Panic if the command was not successful. + panic!("could not emit library file"); + } + + // The bindgen::Builder is the main entry point + // to bindgen, and lets you build up options for + // the resulting bindings. + let bindings = bindgen::Builder::default() + // The input header we would like to generate + // bindings for. + .header(headers_path_str) + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + // Finish the builder and generate the bindings. + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs"); + bindings + .write_to_file(out_path) + .expect("Couldn't write bindings!"); +} +``` diff --git a/book/src/objc.md b/book/src/objc.md index 60e5638dba..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 -`Foo`. The reason this works is beacuse `Foo` represented as `transparent`. -This will be helpful for a lot of objective-c frameworks however there are some +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 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 @@ -32,6 +32,8 @@ methods found in `NSObject`. In order to initialize a class `Foo`, you will have to do something like `let foo = Foo(Foo::alloc().initWithStuff())`. +To blocklist an Objective-C method, you should add the bindgen generated method +path (e.g. `IFoo::method` or `IFoo::class_method`) as a blocklist item. ## Supported Features @@ -40,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 @@ -50,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 8a7cbcb25c..cf719a0d61 100644 --- a/book/src/requirements.md +++ b/book/src/requirements.md @@ -7,17 +7,18 @@ 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 recommended to use Clang 4.0 or greater, however `bindgen` can run with -older Clangs with some features disabled. +It is required to use Clang 9.0 or greater. -* **If you are generating bindings to C++,** you almost definitely want 4.0 or -greater. - -### Installing Clang 4.0 +### Installing Clang #### Windows -Download and install the official pre-built binary from +If you use winget: +```powershell +winget install LLVM.LLVM +``` + +Alternatively, you can download and install the official pre-built binary from [LLVM download page](http://releases.llvm.org/download.html). You will also need to set `LIBCLANG_PATH` as an [environment @@ -47,12 +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 are using older -version of Ubuntu or other Debian-based distros, you may need to add the LLVM -repos to get version 4.0. See http://apt.llvm.org/. +If you want to use the function `bindgen::Builder::dump_preprocessed_input`, then you also need the package `clang`. #### Arch @@ -76,13 +75,13 @@ Add `export LIBCLANG_PATH=/usr/local/lib` to your profile. #### From source -If your package manager doesn't yet offer Clang 4.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 cac4f255c1..a26c393b3b 100644 --- a/book/src/tutorial-1.md +++ b/book/src/tutorial-1.md @@ -3,13 +3,18 @@ First we need to declare a build-time dependency on `bindgen` by adding it to the `[build-dependencies]` section of our crate's `Cargo.toml` file. -Please always use the latest version of `bindgen`, it has the most fixes and -best compatibility. At the time of writing the latest bindgen is `0.53.1`, but -you can always check [the bindgen page of -crates.io](https://crates.io/crates/bindgen) to verify the latest version if -you're unsure. +Please always use the latest version of `bindgen`, as it has the most fixes and +best compatibility. +You can always check the latest version at +[the bindgen page in crates.io](https://crates.io/crates/bindgen). ```toml [build-dependencies] -bindgen = "0.53.1" +bindgen = "0.71.0" ``` + +> ⚠️ **Warning** +> +> `bindgen` needs to be added to the `[build-dependencies]` section, not the normal +> `[dependencies]` section. If you add it as a regular dependency, you will get +> errors like the following: `` error[E0463]: can't find crate for `bindgen` `` diff --git a/book/src/tutorial-3.md b/book/src/tutorial-3.md index 139a24f9a3..3248f2847f 100644 --- a/book/src/tutorial-3.md +++ b/book/src/tutorial-3.md @@ -7,20 +7,20 @@ bindings to `bzip2` at compile time. The resulting bindings will be written to `$OUT_DIR/bindings.rs` where `$OUT_DIR` is chosen by `cargo` and is something like `./target/debug/build/bindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/`. -```rust,ignore -extern crate bindgen; +Note that the associated shared object to `bz2` is `libbz2.so`. In general, a `lib.so` should be referenced in the build file by ``. +```rust,ignore use std::env; use std::path::PathBuf; fn main() { + // Tell cargo to look for shared libraries in the specified directory + println!("cargo:rustc-link-search=/path/to/lib"); + // Tell cargo to tell rustc to link the system bzip2 // shared library. println!("cargo:rustc-link-lib=bz2"); - // Tell cargo to invalidate the built crate whenever the wrapper changes - println!("cargo:rerun-if-changed=wrapper.h"); - // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. @@ -30,7 +30,7 @@ fn main() { .header("wrapper.h") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. - .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. @@ -47,6 +47,6 @@ fn main() { Now, when we run `cargo build`, our bindings to `bzip2` are generated on the fly! -[There's more info about `build.rs` files in the crates.io documentation.][build-rs] +[There's more info about `build.rs` files in the Cargo documentation.][build-rs] -[build-rs]: http://doc.crates.io/build-script.html +[build-rs]: https://doc.rust-lang.org/cargo/reference/build-scripts.html diff --git a/book/src/tutorial-5.md b/book/src/tutorial-5.md index 54b4dda524..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,15 +55,15 @@ 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. let result = BZ2_bzCompressEnd(&mut stream as *mut _); match result { - r if r == (BZ_PARAM_ERROR as _) => panic!(BZ_PARAM_ERROR), + 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 41e07ad703..6aaab2203d 100644 --- a/book/src/using-bitfields.md +++ b/book/src/using-bitfields.md @@ -5,12 +5,17 @@ As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics * Immutable getter functions for each bitfield named `````` * Setter functions for each contiguous block of bitfields named ```set_``` -* Far each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields +* For each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields * A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field. +To keep bindgen from generating the bitfield unit struct, it can be blocklisted like any +other type, i.e. `--blocklist-type "__BindgenBitfieldUnit"`. This may be useful if +you want to define a custom implementation, or your generated bindings import a +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; @@ -71,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/book/src/using-fam.md b/book/src/using-fam.md new file mode 100644 index 0000000000..aaf19c90fd --- /dev/null +++ b/book/src/using-fam.md @@ -0,0 +1,163 @@ +# Using C structures with Flexible Array Members + +Since time immemorial, C programmers have been using what was called "the struct +hack". This is a technique for packing a fixed-size structure and a +variable-sized tail within the same memory allocation. Typically this looks +like: + +```c +struct MyRecord { + time_t timestamp; + unsigned seq; + size_t len; + char payload[0]; +}; +``` + +Because this is so useful, it was standardized in C99 as "flexible array +members", using almost identical syntax: +```c +struct MyRecord { + time_t timestamp; + unsigned seq; + size_t len; + char payload[]; // NOTE: empty [] +}; +``` + +Bindgen supports these structures in two different ways. + +## `__IncompleteArrayField` + +By default, bindgen will generate the corresponding Rust structure: +```rust,ignore +#[repr(C)] +struct MyRecord { + pub timestamp: time_t, + pub seq: ::std::os::raw::c_uint, + pub len: usize, + pub payload: __IncompleteArrayField<::std::os::raw::c_char>, +} +``` + +The `__IncompleteArrayField` type is zero-sized, so this structure represents +the prefix without any trailing data. In order to access that data, it provides +the `as_slice` unsafe method: +```rust,ignore + // SAFETY: there's at least `len` bytes allocated and initialized after `myrecord` + let payload = unsafe { myrecord.payload.as_slice(myrecord.len) }; +``` +There's also `as_mut_slice` which does the obvious. + +These are `unsafe` simply because it's up to you to provide the right length (in +elements of whatever type `payload` is) as there's no way for Rust or Bindgen to +know. In this example, the length is a very straightforward `len` field in the +structure, but it could be encoded in any number of ways within the structure, +or come from somewhere else entirely. + +One big caveat with this technique is that `std::mem::size_of` (or +`size_of_val`) will *only* include the size of the prefix structure. if you're +working out how much storage the whole structure is using, you'll need to add +the suffix yourself. + +## Using Dynamically Sized Types + +If you invoke bindgen with the `--flexarray-dst` option, it will generate +something not quite like this: + +```rust,ignore +#[repr(C)] +struct MyRecord { + pub timestamp: time_t, + pub seq: ::std::os::raw::c_uint, + pub len: usize, + pub payload: [::std::os::raw::c_char], +} +``` +Rust has a set of types which are almost exact analogs for these Flexible Array +Member types: the Dynamically Sized Type ("DST"). + +This looks almost identical to a normal Rust structure, except that you'll note +the type of the `payload` field is a raw slice `[...]` rather than the usual +reference to slice `&[...]`. + +That `payload: [c_char]` is telling Rust that it can't directly know the total +size of this structure - the `payload` field takes an amount of space that's +determined at runtime. This means you can't directly use values of this type, +only references: `&MyRecord`. + +In practice, this is very awkward. So instead, bindgen generates: +```rust,ignore +#[repr(C)] +struct MyRecord { + pub timestamp: time_t, + pub seq: ::std::os::raw::c_uint, + pub len: usize, + pub payload: FAM, +} +``` + +That is: +1. a type parameter `FAM` which represents the type of the `payload` field, +2. it's `?Sized` meaning it can be unsized (ie, a DST) +3. it has the default type of `[c_char; 0]` - that is a zero-sized array of characters + +This means that referencing plain `MyRecord` will be exactly like `MyRecord` +with `__IncompleteArrayField`: it is a fixed-sized structure which you can +manipulate like a normal Rust value. + +But how do you get to the DST part? + +Bindgen will also implement a set of helper methods for this: + +```rust,ignore +// Static sized variant +impl MyRecord<[::std::os::raw::c_char; 0]> { + pub unsafe fn flex_ref(&self, len: usize) -> &MyRecord<[::std::os::raw::c_char]> { ... } + pub unsafe fn flex_mut_ref(&mut self, len: usize) -> &mut MyRecord<[::std::os::raw::c_char]> { ... } + // And some raw pointer variants +} +``` +These will take a sized `MyRecord<[c_char; 0]>` and a length in elements, and +return a reference to a DST `MyRecord<[c_char]>` where the `payload` field is a +fully usable slice of `len` characters. + +The magic here is that the reference is a fat pointer, which not only encodes +the address, but also the dynamic size of the final field, just like a reference +to a slice is. This means that you get full bounds checked access to the +`payload` field like any other Rust slice. + +It also means that doing `mem::size_of_val(myrecord)` will return the *complete* +size of this structure, including the suffix. + +You can go the other way: +```rust,ignore +// Dynamic sized variant +impl MyRecord<[::std::os::raw::c_char]> { + pub fn fixed(&self) -> (&MyRecord<[::std::os::raw::c_char; 0]>, usize) { ... } + pub fn fixed_mut(&mut self) -> (&mut MyRecord<[::std::os::raw::c_char; 0]>, usize) { ... } + pub fn layout(len: usize) -> std::alloc::Layout { ... } +} +``` +which takes the DST variant of the structure and returns the sized variant, +along with the number of elements are after it. These are all completely safe +because all the information needed is part of the fat `&self` reference. + +The `layout` function takes a length and returns the `Layout` - that is, size +and alignment, so that you can allocate memory for the structure (for example, +using `malloc` so you can pass it to a C function). + +Unfortunately the language features needed to support these methods are still unstable: +- [ptr_metadata](https://doc.rust-lang.org/beta/unstable-book/library-features/ptr-metadata.html), + which enables all the fixed<->DST conversions, and +- [layout_for_ptr](https://doc.rust-lang.org/beta/unstable-book/library-features/layout-for-ptr.html), + which allows he `layout` method + +As a result, if you don't specify `--rust-target nightly` you'll just get the +bare type definitions, but no real way to use them. It's often convenient to add +the +```bash +--raw-line '#![feature(ptr_metadata,layout_for_ptr)]' +``` +option if you're generating Rust as a stand-alone crate. Otherwise you'll need +to add the feature line to your containing crate. diff --git a/book/src/using-unions.md b/book/src/using-unions.md index 9e8e9b99d7..5ae764a33d 100644 --- a/book/src/using-unions.md +++ b/book/src/using-unions.md @@ -66,11 +66,11 @@ When using the `union` builtin type, there are two choices for initialization: mod bindings_builtin_union; fn union_builtin() { - // Initalize the union to zero + // Initialize the union to zero let x = bindings_builtin_union::greek_t::default(); // If `--with-derive-default` option is not used, the following may be used - // to initalize the union to zero: + // to initialize the union to zero: let x = unsafe { std::mem::zeroed::() }; // Or, it is possible to initialize exactly one variant of the enum: diff --git a/book/src/visibility.md b/book/src/visibility.md new file mode 100644 index 0000000000..ac0aac15da --- /dev/null +++ b/book/src/visibility.md @@ -0,0 +1,37 @@ +# Making fields private + +Fields can be made private for various reasons. You may wish to enforce some invariant on the fields of a structure, which cannot be achieved if the field is public and can be set by any code. For example, you may wish to ensure that a pointer always points to something appropriate. + +### Annotation + +```c +struct OneFieldPrivate { + /** Null-terminated, static string.
*/ + const char *s; + bool b; +}; + +/**
*/ +struct MostFieldsPrivate { + int a; + bool b; + /**
*/ + char c; +}; +``` + +Then in Rust: + +```rust +# #[repr(C)] +# pub struct OneFieldPrivate { +# s: *const ::std::os::raw::c_char, +# pub b: bool, +# } + +impl OneFieldPrivate { + pub fn new(s: &'static std::ffi::CStr, b: bool) -> Self { + OneFieldPrivate { s: s.as_ptr(), b } + } +} +``` diff --git a/build.rs b/build.rs deleted file mode 100644 index fcc0bb2217..0000000000 --- a/build.rs +++ /dev/null @@ -1,90 +0,0 @@ -mod target { - use std::env; - use std::fs::File; - use std::io::Write; - use std::path::{Path, PathBuf}; - - pub fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - - let mut dst = - File::create(Path::new(&out_dir).join("host-target.txt")).unwrap(); - dst.write_all(env::var("TARGET").unwrap().as_bytes()) - .unwrap(); - } -} - -mod testgen { - use std::char; - use std::env; - use std::ffi::OsStr; - use std::fs::{self, File}; - use std::io::Write; - use std::path::{Path, PathBuf}; - - pub fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - let mut dst = - File::create(Path::new(&out_dir).join("tests.rs")).unwrap(); - - 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, - // We may not have headers directory after packaging. - Err(..) => return, - }; - - let entries = - headers.map(|result| result.expect("Couldn't read header file")); - - 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(), - ) - .unwrap(); - } - _ => {} - } - } - - dst.flush().unwrap(); - } -} - -fn main() { - target::main(); - testgen::main(); - - // On behalf of clang_sys, rebuild ourselves if important configuration - // variables change, to ensure that bindings get rebuilt if the - // underlying libclang changes. - println!("cargo:rerun-if-env-changed=LLVM_CONFIG_PATH"); - println!("cargo:rerun-if-env-changed=LIBCLANG_PATH"); - println!("cargo:rerun-if-env-changed=LIBCLANG_STATIC_PATH"); - 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() - ); - println!( - "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", - std::env::var("TARGET").unwrap().replace("-", "_") - ); -} diff --git a/ci/no-includes.sh b/ci/no-includes.sh index 6aa0fc125e..32c20059e0 100755 --- a/ci/no-includes.sh +++ b/ci/no-includes.sh @@ -1,13 +1,17 @@ #!/usr/bin/env bash # Don't allow any system include directives in tests. +# +# We make an exception for stdarg.h which is used for +# the wrapped va_list feature. stdarg.h is available since C89 +# therefor not having this header is a sign of a bigger issue. set -eu cd "$(dirname "$0")/.." echo "Checking for #include directives of system headers..." -grep -rn '#include\s*<.*>' tests/headers || { +grep -rn '#include\s*<(?!stdarg).*>' bindgen-tests/tests/headers || { echo "Found none; OK!" exit 0 } diff --git a/ci/test.bat b/ci/test.bat index 507537c08e..d4a1c4a08a 100644 --- a/ci/test.bat +++ b/ci/test.bat @@ -29,10 +29,10 @@ findstr /r /c:"#include *<.*>" tests\headers\* >nul 2>&1 && ( cargo test --features "%BINDGEN_FEATURES%" || exit /b 1 call .\ci\assert-no-diff.bat -cargo test --features "%BINDGEN_FEATURES% testing_only_extra_assertions" || exit /b 1 +cargo test --features "%BINDGEN_FEATURES% __testing_only_extra_assertions" || exit /b 1 call .\ci\assert-no-diff.bat -cargo test --release --features "%BINDGEN_FEATURES% testing_only_extra_assertions" || exit /b 1 +cargo test --release --features "%BINDGEN_FEATURES% __testing_only_extra_assertions" || exit /b 1 call .\ci\assert-no-diff.bat ::Now test the expectations' size and alignment tests. diff --git a/ci/test.sh b/ci/test.sh index b58ed0f14d..587263804b 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -8,79 +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() { - echo "x86_64-linux-gnu-ubuntu-16.04" -} - -function llvm_macos_target_triple() { - case "$1" in - [0-8].* | 9.0.0) echo "x86_64-darwin-apple" ;; - # Starting with 9.0.1, triple swapped ordering - *) echo "x86_64-apple-darwin" ;; - esac -} - -function llvm_version_triple() { - case "$1" in - 5.0) echo "5.0.1" ;; - # By default, take the .0 patch release - *) echo "$1.0" ;; - esac -} - -function llvm_base_url() { - local llvm_version_triple=$1 - - case "$llvm_version_triple" in - [0-8].* | 9.0.0) - echo "http://releases.llvm.org/$llvm_version_triple" - ;; - # Starting with 9.0.1, releases are hosted on github - *) - echo "https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvm_version_triple" - ;; - esac -} - -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 -} - -# Need rustfmt to compare the test expectations. -set_rustfmt_env() { - local toolchain="nightly-$(curl https://rust-lang.github.io/rustup-components-history/$(rustup target list --installed | tail -1)/rustfmt)" - rustup update "$toolchain" - rustup component add rustfmt --toolchain "$toolchain" - export RUSTFMT="$(rustup which --toolchain "$toolchain" rustfmt)" + 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() { @@ -89,14 +25,8 @@ assert_no_diff() { git diff-index --quiet HEAD } -set_llvm_env -set_rustfmt_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 @@ -108,10 +38,7 @@ get_cargo_args() { features+="runtime" fi if [ "$BINDGEN_FEATURE_EXTRA_ASSERTS" == "1" ]; then - features+=" testing_only_extra_assertions" - fi - if [ "$BINDGEN_FEATURE_TESTING_ONLY_DOCS" == "1" ]; then - features+=" testing_only_docs" + features+=" __testing_only_extra_assertions" fi if [ ! -z "$features" ]; then args+=" --features $(echo $features | tr ' ' ',')" @@ -119,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 -cargo rustc --lib $CARGO_ARGS -- -Dwarnings +RUSTFLAGS="-Dwarnings" cargo check $CARGO_ARGS -if [ "$BINDGEN_MAIN_TESTS" == "1" ]; then - # Run the 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 new file mode 100644 index 0000000000..ec210a9878 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +missing-docs-in-crate-items = true diff --git a/csmith-fuzzing/predicate.py b/csmith-fuzzing/predicate.py index 8925755c62..6ca5047659 100755 --- a/csmith-fuzzing/predicate.py +++ b/csmith-fuzzing/predicate.py @@ -219,7 +219,7 @@ def run_bindgen(args, bindings): if not args.expect_bindgen_fail and child.returncode != 0: exit_1("Error: running `bindgen` failed", child) - for arg in args.bindings_grep: + for arg in args.bindings_grep or []: pattern = regexp(arg) with open(bindings, mode="r") as f: if not contains(pattern, f): 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/releases/release-announcement-template.md b/releases/release-announcement-template.md index 9f4e87cc4b..c33ef85f4c 100644 --- a/releases/release-announcement-template.md +++ b/releases/release-announcement-template.md @@ -41,7 +41,7 @@ Found a bug with `bindgen`? [File an issue here.][file-issue] [crates.io]: https://crates.io/crates/bindgen [guide]: https://rust-lang.github.io/rust-bindgen [docs]: https://docs.rs/bindgen -[contributing]: https://github.com/rust-lang/rust-bindgen/blob/master/CONTRIBUTING.md +[contributing]: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md [easy]: https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy [less-easy]: https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-less-easy [looking]: https://github.com/rust-lang/rust-bindgen/issues/747 diff --git a/src/callbacks.rs b/src/callbacks.rs deleted file mode 100644 index 9b34544947..0000000000 --- a/src/callbacks.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! A public API for more fine-grained customization of bindgen behavior. - -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; -use std::fmt; -use std::panic::UnwindSafe; - -/// An enum to allow ignoring parsing of macros. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum MacroParsingBehavior { - /// Ignore the macro, generating no code for it, or anything that depends on - /// it. - Ignore, - /// The default behavior bindgen would have otherwise. - Default, -} - -impl Default for MacroParsingBehavior { - fn default() -> Self { - MacroParsingBehavior::Default - } -} - -/// A trait to allow configuring different kinds of types in different -/// situations. -pub trait ParseCallbacks: fmt::Debug + UnwindSafe { - /// This function will be run on every macro that is identified. - fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { - MacroParsingBehavior::Default - } - - /// 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 { - None - } - - /// This will be run on every string macro. The callback cannot influence the further - /// treatment of the macro, but may use the value to generate additional code or configuration. - fn str_macro(&self, _name: &str, _value: &[u8]) {} - - /// This will be run on every function-like macro. The callback cannot - /// influence the further treatment of the macro, but may use the value to - /// generate additional code or configuration. - /// - /// The first parameter represents the name and argument list (including the - /// parentheses) of the function-like macro. The second parameter represents - /// the expansion of the macro as a sequence of tokens. - fn func_macro(&self, _name: &str, _value: &[&[u8]]) {} - - /// This function should return whether, given an enum variant - /// name, and value, this enum variant will forcibly be a constant. - fn enum_variant_behavior( - &self, - _enum_name: Option<&str>, - _original_variant_name: &str, - _variant_value: EnumVariantValue, - ) -> Option { - None - } - - /// Allows to rename an enum variant, replacing `_original_variant_name`. - fn enum_variant_name( - &self, - _enum_name: Option<&str>, - _original_variant_name: &str, - _variant_value: EnumVariantValue, - ) -> Option { - None - } - - /// Allows to rename an item, replacing `_original_item_name`. - fn item_name(&self, _original_item_name: &str) -> Option { - None - } - - /// This will be called on every file inclusion, with the full path of the included file. - fn include_file(&self, _filename: &str) {} - - /// This will be called to determine whether a particular blocklisted type - /// implements a trait or not. This will be used to implement traits on - /// other types containing the blocklisted type. - /// - /// * `None`: use the default behavior - /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait` - /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't - /// derive `_derive_trait` but can implemented it manually - /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait` - fn blocklisted_type_implements_trait( - &self, - _name: &str, - _derive_trait: DeriveTrait, - ) -> Option { - None - } - - /// Provide a list of custom derive attributes. - /// - /// If no additional attributes are wanted, this function should return an - /// empty `Vec`. - fn add_derives(&self, _name: &str) -> Vec { - vec![] - } -} diff --git a/src/clang.rs b/src/clang.rs deleted file mode 100644 index 528c8a9111..0000000000 --- a/src/clang.rs +++ /dev/null @@ -1,2087 +0,0 @@ -//! A higher level Clang API built on top of the generated bindings in the -//! `clang_sys` module. - -#![allow(non_upper_case_globals, dead_code)] - -use crate::ir::context::BindgenContext; -use clang_sys::*; -use std::ffi::{CStr, CString}; -use std::fmt; -use std::hash::Hash; -use std::hash::Hasher; -use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; -use std::{mem, ptr, slice}; - -/// A cursor into the Clang AST, pointing to an AST node. -/// -/// We call the AST node pointed to by the cursor the cursor's "referent". -#[derive(Copy, Clone)] -pub struct Cursor { - x: CXCursor, -} - -impl fmt::Debug for Cursor { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!( - fmt, - "Cursor({} kind: {}, loc: {}, usr: {:?})", - self.spelling(), - kind_to_str(self.kind()), - self.location(), - self.usr() - ) - } -} - -impl Cursor { - /// Get the Unified Symbol Resolution for this cursor's referent, if - /// available. - /// - /// The USR can be used to compare entities across translation units. - pub fn usr(&self) -> Option { - let s = unsafe { cxstring_into_string(clang_getCursorUSR(self.x)) }; - if s.is_empty() { - None - } else { - Some(s) - } - } - - /// Is this cursor's referent a declaration? - pub fn is_declaration(&self) -> bool { - unsafe { clang_isDeclaration(self.kind()) != 0 } - } - - /// Get this cursor's referent's spelling. - pub fn spelling(&self) -> String { - unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) } - } - - /// Get this cursor's referent's display name. - /// - /// This is not necessarily a valid identifier. It includes extra - /// information, such as parameters for a function, etc. - pub fn display_name(&self) -> String { - unsafe { cxstring_into_string(clang_getCursorDisplayName(self.x)) } - } - - /// Get the mangled name of this cursor's referent. - pub fn mangling(&self) -> String { - unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) } - } - - /// Gets the C++ manglings for this cursor, or an error if the manglings - /// are not available. - pub fn cxx_manglings(&self) -> Result, ()> { - use clang_sys::*; - unsafe { - let manglings = clang_Cursor_getCXXManglings(self.x); - if manglings.is_null() { - return Err(()); - } - let count = (*manglings).Count as usize; - - let mut result = Vec::with_capacity(count); - for i in 0..count { - let string_ptr = (*manglings).Strings.add(i); - result.push(cxstring_to_string_leaky(*string_ptr)); - } - clang_disposeStringSet(manglings); - Ok(result) - } - } - - /// Returns whether the cursor refers to a built-in definition. - pub fn is_builtin(&self) -> bool { - let (file, _, _, _) = self.location().location(); - file.name().is_none() - } - - /// Get the `Cursor` for this cursor's referent's lexical parent. - /// - /// The lexical parent is the parent of the definition. The semantic parent - /// is the parent of the declaration. Generally, the lexical parent doesn't - /// have any effect on semantics, while the semantic parent does. - /// - /// In the following snippet, the `Foo` class would be the semantic parent - /// of the out-of-line `method` definition, while the lexical parent is the - /// translation unit. - /// - /// ```c++ - /// class Foo { - /// void method(); - /// }; - /// - /// void Foo::method() { /* ... */ } - /// ``` - pub fn lexical_parent(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getCursorLexicalParent(self.x), - } - } - } - - /// Get the referent's semantic parent, if one is available. - /// - /// See documentation for `lexical_parent` for details on semantic vs - /// lexical parents. - pub fn fallible_semantic_parent(&self) -> Option { - let sp = unsafe { - Cursor { - x: clang_getCursorSemanticParent(self.x), - } - }; - if sp == *self || !sp.is_valid() { - return None; - } - Some(sp) - } - - /// Get the referent's semantic parent. - /// - /// See documentation for `lexical_parent` for details on semantic vs - /// lexical parents. - pub fn semantic_parent(&self) -> Cursor { - self.fallible_semantic_parent().unwrap() - } - - /// Return the number of template arguments used by this cursor's referent, - /// if the referent is either a template instantiation. Returns `None` - /// otherwise. - /// - /// NOTE: This may not return `Some` for partial template specializations, - /// see #193 and #194. - pub fn num_template_args(&self) -> Option { - // XXX: `clang_Type_getNumTemplateArguments` is sort of reliable, while - // `clang_Cursor_getNumTemplateArguments` is totally unreliable. - // Therefore, try former first, and only fallback to the latter if we - // have to. - self.cur_type() - .num_template_args() - .or_else(|| { - let n: c_int = - unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; - - if n >= 0 { - Some(n as u32) - } else { - debug_assert_eq!(n, -1); - None - } - }) - .or_else(|| { - let canonical = self.canonical(); - if canonical != *self { - canonical.num_template_args() - } else { - None - } - }) - } - - /// Get a cursor pointing to this referent's containing translation unit. - /// - /// Note that we shouldn't create a `TranslationUnit` struct here, because - /// bindgen assumes there will only be one of them alive at a time, and - /// disposes it on drop. That can change if this would be required, but I - /// think we can survive fine without it. - pub fn translation_unit(&self) -> Cursor { - assert!(self.is_valid()); - unsafe { - let tu = clang_Cursor_getTranslationUnit(self.x); - let cursor = Cursor { - x: clang_getTranslationUnitCursor(tu), - }; - assert!(cursor.is_valid()); - cursor - } - } - - /// Is the referent a top level construct? - pub fn is_toplevel(&self) -> bool { - let mut semantic_parent = self.fallible_semantic_parent(); - - while semantic_parent.is_some() && - (semantic_parent.unwrap().kind() == CXCursor_Namespace || - semantic_parent.unwrap().kind() == - CXCursor_NamespaceAlias || - semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) - { - semantic_parent = - semantic_parent.unwrap().fallible_semantic_parent(); - } - - let tu = self.translation_unit(); - // Yes, this can happen with, e.g., macro definitions. - semantic_parent == tu.fallible_semantic_parent() - } - - /// There are a few kinds of types that we need to treat specially, mainly - /// not tracking the type declaration but the location of the cursor, given - /// clang doesn't expose a proper declaration for these types. - pub fn is_template_like(&self) -> bool { - matches!( - self.kind(), - CXCursor_ClassTemplate | - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl - ) - } - - /// Is this Cursor pointing to a function-like macro definition? - pub fn is_macro_function_like(&self) -> bool { - unsafe { clang_Cursor_isMacroFunctionLike(self.x) != 0 } - } - - /// Get the kind of referent this cursor is pointing to. - pub fn kind(&self) -> CXCursorKind { - self.x.kind - } - - /// Returns true if the cursor is a definition - pub fn is_definition(&self) -> bool { - unsafe { clang_isCursorDefinition(self.x) != 0 } - } - - /// Is the referent a template specialization? - pub fn is_template_specialization(&self) -> bool { - self.specialized().is_some() - } - - /// Is the referent a fully specialized template specialization without any - /// remaining free template arguments? - pub fn is_fully_specialized_template(&self) -> bool { - self.is_template_specialization() && - self.kind() != CXCursor_ClassTemplatePartialSpecialization && - self.num_template_args().unwrap_or(0) > 0 - } - - /// Is the referent a template specialization that still has remaining free - /// template arguments? - pub fn is_in_non_fully_specialized_template(&self) -> bool { - if self.is_toplevel() { - return false; - } - - let parent = self.semantic_parent(); - if parent.is_fully_specialized_template() { - return false; - } - - if !parent.is_template_like() { - return parent.is_in_non_fully_specialized_template(); - } - - true - } - - /// Is this cursor pointing a valid referent? - pub fn is_valid(&self) -> bool { - unsafe { clang_isInvalid(self.kind()) == 0 } - } - - /// Get the source location for the referent. - pub fn location(&self) -> SourceLocation { - unsafe { - SourceLocation { - x: clang_getCursorLocation(self.x), - } - } - } - - /// Get the source location range for the referent. - pub fn extent(&self) -> CXSourceRange { - unsafe { clang_getCursorExtent(self.x) } - } - - /// Get the raw declaration comment for this referent, if one exists. - pub fn raw_comment(&self) -> Option { - let s = unsafe { - cxstring_into_string(clang_Cursor_getRawCommentText(self.x)) - }; - if s.is_empty() { - None - } else { - Some(s) - } - } - - /// Get the referent's parsed comment. - pub fn comment(&self) -> Comment { - unsafe { - Comment { - x: clang_Cursor_getParsedComment(self.x), - } - } - } - - /// Get the referent's type. - pub fn cur_type(&self) -> Type { - unsafe { - Type { - x: clang_getCursorType(self.x), - } - } - } - - /// Given that this cursor's referent is a reference to another type, or is - /// a declaration, get the cursor pointing to the referenced type or type of - /// the declared thing. - pub fn definition(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getCursorDefinition(self.x), - }; - - if ret.is_valid() && ret.kind() != CXCursor_NoDeclFound { - Some(ret) - } else { - None - } - } - } - - /// Given that this cursor's referent is reference type, get the cursor - /// pointing to the referenced type. - pub fn referenced(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getCursorReferenced(self.x), - }; - - if ret.is_valid() { - Some(ret) - } else { - None - } - } - } - - /// Get the canonical cursor for this referent. - /// - /// Many types can be declared multiple times before finally being properly - /// defined. This method allows us to get the canonical cursor for the - /// referent type. - pub fn canonical(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getCanonicalCursor(self.x), - } - } - } - - /// Given that this cursor points to either a template specialization or a - /// template instantiation, get a cursor pointing to the template definition - /// that is being specialized. - pub fn specialized(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getSpecializedCursorTemplate(self.x), - }; - if ret.is_valid() { - Some(ret) - } else { - None - } - } - } - - /// Assuming that this cursor's referent is a template declaration, get the - /// kind of cursor that would be generated for its specializations. - pub fn template_kind(&self) -> CXCursorKind { - unsafe { clang_getTemplateCursorKind(self.x) } - } - - /// Traverse this cursor's referent and its children. - /// - /// Call the given function on each AST node traversed. - pub fn visit(&self, mut visitor: Visitor) - where - Visitor: FnMut(Cursor) -> CXChildVisitResult, - { - let data = &mut visitor as *mut Visitor; - unsafe { - clang_visitChildren(self.x, visit_children::, data.cast()); - } - } - - /// Collect all of this cursor's children into a vec and return them. - pub fn collect_children(&self) -> Vec { - let mut children = vec![]; - self.visit(|c| { - children.push(c); - CXChildVisit_Continue - }); - children - } - - /// Does this cursor have any children? - pub fn has_children(&self) -> bool { - let mut has_children = false; - self.visit(|_| { - has_children = true; - CXChildVisit_Break - }); - has_children - } - - /// Does this cursor have at least `n` children? - pub fn has_at_least_num_children(&self, n: usize) -> bool { - assert!(n > 0); - let mut num_left = n; - self.visit(|_| { - num_left -= 1; - if num_left == 0 { - CXChildVisit_Break - } else { - CXChildVisit_Continue - } - }); - num_left == 0 - } - - /// Returns whether the given location contains a cursor with the given - /// kind in the first level of nesting underneath (doesn't look - /// recursively). - pub fn contains_cursor(&self, kind: CXCursorKind) -> bool { - let mut found = false; - - self.visit(|c| { - if c.kind() == kind { - found = true; - CXChildVisit_Break - } else { - CXChildVisit_Continue - } - }); - - found - } - - /// Is the referent an inlined function? - pub fn is_inlined_function(&self) -> bool { - unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } - } - - /// Is the referent a defaulted function? - pub fn is_defaulted_function(&self) -> bool { - unsafe { clang_CXXMethod_isDefaulted(self.x) != 0 } - } - - /// Is the referent a deleted function? - pub fn is_deleted_function(&self) -> bool { - // Unfortunately, libclang doesn't yet have an API for checking if a - // member function is deleted, but the following should be a good - // enough approximation. - // Deleted functions are implicitly inline according to paragraph 4 of - // [dcl.fct.def.delete] in the C++ standard. Normal inline functions - // have a definition in the same translation unit, so if this is an - // inline function without a definition, and it's not a defaulted - // function, we can reasonably safely conclude that it's a deleted - // function. - self.is_inlined_function() && - self.definition().is_none() && - !self.is_defaulted_function() - } - - /// Get the width of this cursor's referent bit field, or `None` if the - /// referent is not a bit field. - pub fn bit_width(&self) -> Option { - unsafe { - let w = clang_getFieldDeclBitWidth(self.x); - if w == -1 { - None - } else { - Some(w as u32) - } - } - } - - /// Get the integer representation type used to hold this cursor's referent - /// enum type. - pub fn enum_type(&self) -> Option { - unsafe { - let t = Type { - x: clang_getEnumDeclIntegerType(self.x), - }; - if t.is_valid() { - Some(t) - } else { - None - } - } - } - - /// Get the boolean constant value for this cursor's enum variant referent. - /// - /// Returns None if the cursor's referent is not an enum variant. - pub fn enum_val_boolean(&self) -> Option { - unsafe { - if self.kind() == CXCursor_EnumConstantDecl { - Some(clang_getEnumConstantDeclValue(self.x) != 0) - } else { - None - } - } - } - - /// Get the signed constant value for this cursor's enum variant referent. - /// - /// Returns None if the cursor's referent is not an enum variant. - pub fn enum_val_signed(&self) -> Option { - unsafe { - if self.kind() == CXCursor_EnumConstantDecl { - Some(clang_getEnumConstantDeclValue(self.x) as i64) - } else { - None - } - } - } - - /// Get the unsigned constant value for this cursor's enum variant referent. - /// - /// Returns None if the cursor's referent is not an enum variant. - pub fn enum_val_unsigned(&self) -> Option { - unsafe { - if self.kind() == CXCursor_EnumConstantDecl { - Some(clang_getEnumConstantDeclUnsignedValue(self.x) as u64) - } else { - None - } - } - } - - /// Whether this cursor has the `warn_unused_result` attribute. - pub fn has_warn_unused_result_attr(&self) -> bool { - // FIXME(emilio): clang-sys doesn't expose this (from clang 9). - const CXCursor_WarnUnusedResultAttr: CXCursorKind = 440; - self.has_attr("warn_unused_result", Some(CXCursor_WarnUnusedResultAttr)) - } - - /// Does this cursor have the given attribute? - /// - /// `name` is checked against unexposed attributes. - fn has_attr(&self, name: &str, clang_kind: Option) -> bool { - let mut found_attr = false; - self.visit(|cur| { - let kind = cur.kind(); - found_attr = clang_kind.map_or(false, |k| k == kind) || - (kind == CXCursor_UnexposedAttr && - cur.tokens().iter().any(|t| { - t.kind == CXToken_Identifier && - t.spelling() == name.as_bytes() - })); - - if found_attr { - CXChildVisit_Break - } else { - CXChildVisit_Continue - } - }); - - found_attr - } - - /// Given that this cursor's referent is a `typedef`, get the `Type` that is - /// being aliased. - pub fn typedef_type(&self) -> Option { - let inner = Type { - x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) }, - }; - - if inner.is_valid() { - Some(inner) - } else { - None - } - } - - /// Get the linkage kind for this cursor's referent. - /// - /// This only applies to functions and variables. - pub fn linkage(&self) -> CXLinkageKind { - unsafe { clang_getCursorLinkage(self.x) } - } - - /// Get the visibility of this cursor's referent. - pub fn visibility(&self) -> CXVisibilityKind { - unsafe { clang_getCursorVisibility(self.x) } - } - - /// Given that this cursor's referent is a function, return cursors to its - /// parameters. - /// - /// Returns None if the cursor's referent is not a function/method call or - /// declaration. - pub fn args(&self) -> Option> { - // match self.kind() { - // CXCursor_FunctionDecl | - // CXCursor_CXXMethod => { - self.num_args().ok().map(|num| { - (0..num) - .map(|i| Cursor { - x: unsafe { clang_Cursor_getArgument(self.x, i as c_uint) }, - }) - .collect() - }) - } - - /// Given that this cursor's referent is a function/method call or - /// declaration, return the number of arguments it takes. - /// - /// Returns Err if the cursor's referent is not a function/method call or - /// declaration. - pub fn num_args(&self) -> Result { - unsafe { - let w = clang_Cursor_getNumArguments(self.x); - if w == -1 { - Err(()) - } else { - Ok(w as u32) - } - } - } - - /// Get the access specifier for this cursor's referent. - pub fn access_specifier(&self) -> CX_CXXAccessSpecifier { - unsafe { clang_getCXXAccessSpecifier(self.x) } - } - - /// Is the cursor's referrent publically accessible in C++? - /// - /// Returns true if self.access_specifier() is `CX_CXXPublic` or - /// `CX_CXXInvalidAccessSpecifier`. - pub fn public_accessible(&self) -> bool { - let access = self.access_specifier(); - access == CX_CXXPublic || access == CX_CXXInvalidAccessSpecifier - } - - /// Is this cursor's referent a field declaration that is marked as - /// `mutable`? - pub fn is_mutable_field(&self) -> bool { - unsafe { clang_CXXField_isMutable(self.x) != 0 } - } - - /// Get the offset of the field represented by the Cursor. - pub fn offset_of_field(&self) -> Result { - let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) }; - - if offset < 0 { - Err(LayoutError::from(offset as i32)) - } else { - Ok(offset as usize) - } - } - - /// Is this cursor's referent a member function that is declared `static`? - pub fn method_is_static(&self) -> bool { - unsafe { clang_CXXMethod_isStatic(self.x) != 0 } - } - - /// Is this cursor's referent a member function that is declared `const`? - pub fn method_is_const(&self) -> bool { - unsafe { clang_CXXMethod_isConst(self.x) != 0 } - } - - /// Is this cursor's referent a member function that is virtual? - pub fn method_is_virtual(&self) -> bool { - unsafe { clang_CXXMethod_isVirtual(self.x) != 0 } - } - - /// Is this cursor's referent a member function that is pure virtual? - pub fn method_is_pure_virtual(&self) -> bool { - unsafe { clang_CXXMethod_isPureVirtual(self.x) != 0 } - } - - /// Is this cursor's referent a struct or class with virtual members? - pub fn is_virtual_base(&self) -> bool { - unsafe { clang_isVirtualBase(self.x) != 0 } - } - - /// Try to evaluate this cursor. - pub fn evaluate(&self) -> Option { - EvalResult::new(*self) - } - - /// Return the result type for this cursor - pub fn ret_type(&self) -> Option { - let rt = Type { - x: unsafe { clang_getCursorResultType(self.x) }, - }; - if rt.is_valid() { - Some(rt) - } else { - None - } - } - - /// Gets the tokens that correspond to that cursor. - pub fn tokens(&self) -> RawTokens { - RawTokens::new(self) - } - - /// Gets the tokens that correspond to that cursor as `cexpr` tokens. - pub fn cexpr_tokens(self) -> Vec { - self.tokens() - .iter() - .filter_map(|token| token.as_cexpr_token()) - .collect() - } - - /// 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 fn get_included_file_name(&self) -> Option { - let file = unsafe { clang_sys::clang_getIncludedFile(self.x) }; - if file.is_null() { - None - } else { - Some(unsafe { - cxstring_into_string(clang_sys::clang_getFileName(file)) - }) - } - } -} - -/// A struct that owns the tokenizer result from a given cursor. -pub struct RawTokens<'a> { - cursor: &'a Cursor, - tu: CXTranslationUnit, - tokens: *mut CXToken, - token_count: c_uint, -} - -impl<'a> RawTokens<'a> { - fn new(cursor: &'a Cursor) -> Self { - let mut tokens = ptr::null_mut(); - let mut token_count = 0; - let range = cursor.extent(); - let tu = unsafe { clang_Cursor_getTranslationUnit(cursor.x) }; - unsafe { clang_tokenize(tu, range, &mut tokens, &mut token_count) }; - Self { - cursor, - tu, - tokens, - token_count, - } - } - - fn as_slice(&self) -> &[CXToken] { - if self.tokens.is_null() { - return &[]; - } - unsafe { slice::from_raw_parts(self.tokens, self.token_count as usize) } - } - - /// Get an iterator over these tokens. - pub fn iter(&self) -> ClangTokenIterator { - ClangTokenIterator { - tu: self.tu, - raw: self.as_slice().iter(), - } - } -} - -impl<'a> Drop for RawTokens<'a> { - fn drop(&mut self) { - if !self.tokens.is_null() { - unsafe { - clang_disposeTokens( - self.tu, - self.tokens, - self.token_count as c_uint, - ); - } - } - } -} - -/// A raw clang token, that exposes only kind, spelling, and extent. This is a -/// slightly more convenient version of `CXToken` which owns the spelling -/// string and extent. -#[derive(Debug)] -pub struct ClangToken { - spelling: CXString, - /// The extent of the token. This is the same as the relevant member from - /// `CXToken`. - pub extent: CXSourceRange, - /// The kind of the token. This is the same as the relevant member from - /// `CXToken`. - pub kind: CXTokenKind, -} - -impl ClangToken { - /// Get the token spelling, without being converted to utf-8. - pub fn spelling(&self) -> &[u8] { - let c_str = unsafe { - CStr::from_ptr(clang_getCString(self.spelling) as *const _) - }; - c_str.to_bytes() - } - - /// Converts a ClangToken to a `cexpr` token if possible. - pub fn as_cexpr_token(&self) -> Option { - use cexpr::token; - - let kind = match self.kind { - CXToken_Punctuation => token::Kind::Punctuation, - CXToken_Literal => token::Kind::Literal, - CXToken_Identifier => token::Kind::Identifier, - CXToken_Keyword => token::Kind::Keyword, - // NB: cexpr is not too happy about comments inside - // expressions, so we strip them down here. - CXToken_Comment => return None, - _ => { - warn!("Found unexpected token kind: {:?}", self); - return None; - } - }; - - Some(token::Token { - kind, - raw: self.spelling().to_vec().into_boxed_slice(), - }) - } -} - -impl Drop for ClangToken { - fn drop(&mut self) { - unsafe { clang_disposeString(self.spelling) } - } -} - -/// An iterator over a set of Tokens. -pub struct ClangTokenIterator<'a> { - tu: CXTranslationUnit, - raw: slice::Iter<'a, CXToken>, -} - -impl<'a> Iterator for ClangTokenIterator<'a> { - type Item = ClangToken; - - fn next(&mut self) -> Option { - let raw = self.raw.next()?; - unsafe { - let kind = clang_getTokenKind(*raw); - let spelling = clang_getTokenSpelling(self.tu, *raw); - let extent = clang_getTokenExtent(self.tu, *raw); - Some(ClangToken { - kind, - extent, - spelling, - }) - } - } -} - -/// Checks whether the name looks like an identifier, i.e. is alphanumeric -/// (including '_') and does not start with a digit. -pub 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); - - first_valid && chars.all(|c| c.is_alphanumeric() || c == '_') -} - -extern "C" fn visit_children( - cur: CXCursor, - _parent: CXCursor, - data: CXClientData, -) -> CXChildVisitResult -where - Visitor: FnMut(Cursor) -> CXChildVisitResult, -{ - let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) }; - let child = Cursor { x: cur }; - - (*func)(child) -} - -impl PartialEq for Cursor { - fn eq(&self, other: &Cursor) -> bool { - unsafe { clang_equalCursors(self.x, other.x) == 1 } - } -} - -impl Eq for Cursor {} - -impl Hash for Cursor { - fn hash(&self, state: &mut H) { - unsafe { clang_hashCursor(self.x) }.hash(state) - } -} - -/// The type of a node in clang's AST. -#[derive(Clone, Copy)] -pub struct Type { - x: CXType, -} - -impl PartialEq for Type { - fn eq(&self, other: &Self) -> bool { - unsafe { clang_equalTypes(self.x, other.x) != 0 } - } -} - -impl Eq for Type {} - -impl fmt::Debug for Type { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!( - fmt, - "Type({}, kind: {}, cconv: {}, decl: {:?}, canon: {:?})", - self.spelling(), - type_to_str(self.kind()), - self.call_conv(), - self.declaration(), - self.declaration().canonical() - ) - } -} - -/// An error about the layout of a struct, class, or type. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum LayoutError { - /// Asked for the layout of an invalid type. - Invalid, - /// Asked for the layout of an incomplete type. - Incomplete, - /// Asked for the layout of a dependent type. - Dependent, - /// Asked for the layout of a type that does not have constant size. - NotConstantSize, - /// Asked for the layout of a field in a type that does not have such a - /// field. - InvalidFieldName, - /// An unknown layout error. - Unknown, -} - -impl ::std::convert::From for LayoutError { - fn from(val: i32) -> Self { - use self::LayoutError::*; - - match val { - CXTypeLayoutError_Invalid => Invalid, - CXTypeLayoutError_Incomplete => Incomplete, - CXTypeLayoutError_Dependent => Dependent, - CXTypeLayoutError_NotConstantSize => NotConstantSize, - CXTypeLayoutError_InvalidFieldName => InvalidFieldName, - _ => Unknown, - } - } -} - -impl Type { - /// Get this type's kind. - pub fn kind(&self) -> CXTypeKind { - self.x.kind - } - - /// Get a cursor pointing to this type's declaration. - pub fn declaration(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getTypeDeclaration(self.x), - } - } - } - - /// Get the canonical declaration of this type, if it is available. - pub fn canonical_declaration( - &self, - location: Option<&Cursor>, - ) -> Option { - let mut declaration = self.declaration(); - if !declaration.is_valid() { - if let Some(location) = location { - let mut location = *location; - if let Some(referenced) = location.referenced() { - location = referenced; - } - if location.is_template_like() { - declaration = location; - } - } - } - - let canonical = declaration.canonical(); - if canonical.is_valid() && canonical.kind() != CXCursor_NoDeclFound { - Some(CanonicalTypeDeclaration(*self, canonical)) - } else { - None - } - } - - /// Get a raw display name for this type. - pub fn spelling(&self) -> String { - let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }; - // Clang 5.0 introduced changes in the spelling API so it returned the - // full qualified name. Let's undo that here. - if s.split("::").all(is_valid_identifier) { - if let Some(s) = s.split("::").last() { - return s.to_owned(); - } - } - - s - } - - /// Is this type const qualified? - pub fn is_const(&self) -> bool { - unsafe { clang_isConstQualifiedType(self.x) != 0 } - } - - #[inline] - fn is_non_deductible_auto_type(&self) -> bool { - debug_assert_eq!(self.kind(), CXType_Auto); - self.canonical_type() == *self - } - - #[inline] - fn clang_size_of(&self, ctx: &BindgenContext) -> c_longlong { - match self.kind() { - // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975 - CXType_RValueReference | CXType_LValueReference => { - ctx.target_pointer_size() as c_longlong - } - // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => -6, - _ => unsafe { clang_Type_getSizeOf(self.x) }, - } - } - - #[inline] - fn clang_align_of(&self, ctx: &BindgenContext) -> c_longlong { - match self.kind() { - // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975 - CXType_RValueReference | CXType_LValueReference => { - ctx.target_pointer_size() as c_longlong - } - // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => -6, - _ => unsafe { clang_Type_getAlignOf(self.x) }, - } - } - - /// What is the size of this type? Paper over invalid types by returning `0` - /// for them. - pub fn size(&self, ctx: &BindgenContext) -> usize { - let val = self.clang_size_of(ctx); - if val < 0 { - 0 - } else { - val as usize - } - } - - /// What is the size of this type? - pub fn fallible_size( - &self, - ctx: &BindgenContext, - ) -> Result { - let val = self.clang_size_of(ctx); - if val < 0 { - Err(LayoutError::from(val as i32)) - } else { - Ok(val as usize) - } - } - - /// What is the alignment of this type? Paper over invalid types by - /// returning `0`. - pub fn align(&self, ctx: &BindgenContext) -> usize { - let val = self.clang_align_of(ctx); - if val < 0 { - 0 - } else { - val as usize - } - } - - /// What is the alignment of this type? - pub fn fallible_align( - &self, - ctx: &BindgenContext, - ) -> Result { - let val = self.clang_align_of(ctx); - if val < 0 { - Err(LayoutError::from(val as i32)) - } else { - Ok(val as usize) - } - } - - /// Get the layout for this type, or an error describing why it does not - /// have a valid layout. - pub fn fallible_layout( - &self, - ctx: &BindgenContext, - ) -> Result { - use crate::ir::layout::Layout; - let size = self.fallible_size(ctx)?; - let align = self.fallible_align(ctx)?; - Ok(Layout::new(size, align)) - } - - /// Get the number of template arguments this type has, or `None` if it is - /// not some kind of template. - pub fn num_template_args(&self) -> Option { - let n = unsafe { clang_Type_getNumTemplateArguments(self.x) }; - if n >= 0 { - Some(n as u32) - } else { - debug_assert_eq!(n, -1); - None - } - } - - /// If this type is a class template specialization, return its - /// template arguments. Otherwise, return None. - pub fn template_args(&self) -> Option { - self.num_template_args().map(|n| TypeTemplateArgIterator { - x: self.x, - length: n, - index: 0, - }) - } - - /// Given that this type is a function prototype, return the types of its parameters. - /// - /// Returns None if the type is not a function prototype. - pub fn args(&self) -> Option> { - self.num_args().ok().map(|num| { - (0..num) - .map(|i| Type { - x: unsafe { clang_getArgType(self.x, i as c_uint) }, - }) - .collect() - }) - } - - /// Given that this type is a function prototype, return the number of arguments it takes. - /// - /// Returns Err if the type is not a function prototype. - pub fn num_args(&self) -> Result { - unsafe { - let w = clang_getNumArgTypes(self.x); - if w == -1 { - Err(()) - } else { - Ok(w as u32) - } - } - } - - /// Given that this type is a pointer type, return the type that it points - /// to. - pub fn pointee_type(&self) -> Option { - match self.kind() { - CXType_Pointer | - CXType_RValueReference | - CXType_LValueReference | - CXType_MemberPointer | - CXType_BlockPointer | - CXType_ObjCObjectPointer => { - let ret = Type { - x: unsafe { clang_getPointeeType(self.x) }, - }; - debug_assert!(ret.is_valid()); - Some(ret) - } - _ => None, - } - } - - /// Given that this type is an array, vector, or complex type, return the - /// type of its elements. - pub fn elem_type(&self) -> Option { - let current_type = Type { - x: unsafe { clang_getElementType(self.x) }, - }; - if current_type.is_valid() { - Some(current_type) - } else { - None - } - } - - /// Given that this type is an array or vector type, return its number of - /// elements. - pub 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 { - None - } - } - - /// Get the canonical version of this type. This sees through `typedef`s and - /// aliases to get the underlying, canonical type. - pub fn canonical_type(&self) -> Type { - unsafe { - Type { - x: clang_getCanonicalType(self.x), - } - } - } - - /// Is this type a variadic function type? - pub fn is_variadic(&self) -> bool { - unsafe { clang_isFunctionTypeVariadic(self.x) != 0 } - } - - /// Given that this type is a function type, get the type of its return - /// value. - pub fn ret_type(&self) -> Option { - let rt = Type { - x: unsafe { clang_getResultType(self.x) }, - }; - if rt.is_valid() { - Some(rt) - } else { - None - } - } - - /// Given that this type is a function type, get its calling convention. If - /// this is not a function type, `CXCallingConv_Invalid` is returned. - pub fn call_conv(&self) -> CXCallingConv { - unsafe { clang_getFunctionTypeCallingConv(self.x) } - } - - /// For elaborated types (types which use `class`, `struct`, or `union` to - /// disambiguate types from local bindings), get the underlying type. - pub fn named(&self) -> Type { - unsafe { - Type { - x: clang_Type_getNamedType(self.x), - } - } - } - - /// Is this a valid type? - pub fn is_valid(&self) -> bool { - self.kind() != CXType_Invalid - } - - /// Is this a valid and exposed type? - pub fn is_valid_and_exposed(&self) -> bool { - self.is_valid() && self.kind() != CXType_Unexposed - } - - /// Is this type a fully instantiated template? - pub fn is_fully_instantiated_template(&self) -> bool { - // 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) && - !matches!( - self.declaration().kind(), - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl | - CXCursor_TemplateTemplateParameter - ) - } - - /// Is this type an associated template type? Eg `T::Associated` in - /// this example: - /// - /// ```c++ - /// template - /// class Foo { - /// typename T::Associated member; - /// }; - /// ``` - pub fn is_associated_type(&self) -> bool { - // This is terrible :( - fn hacky_parse_associated_type>(spelling: S) -> bool { - lazy_static! { - static ref ASSOC_TYPE_RE: regex::Regex = regex::Regex::new( - r"typename type\-parameter\-\d+\-\d+::.+" - ) - .unwrap(); - } - ASSOC_TYPE_RE.is_match(spelling.as_ref()) - } - - self.kind() == CXType_Unexposed && - (hacky_parse_associated_type(self.spelling()) || - hacky_parse_associated_type( - self.canonical_type().spelling(), - )) - } -} - -/// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its -/// cursor is the canonical declaration for its type. If you have a -/// `CanonicalTypeDeclaration` instance, you know for sure that the type and -/// cursor match up in a canonical declaration relationship, and it simply -/// cannot be otherwise. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct CanonicalTypeDeclaration(Type, Cursor); - -impl CanonicalTypeDeclaration { - /// Get the type. - pub fn ty(&self) -> &Type { - &self.0 - } - - /// Get the type's canonical declaration cursor. - pub fn cursor(&self) -> &Cursor { - &self.1 - } -} - -/// An iterator for a type's template arguments. -pub struct TypeTemplateArgIterator { - x: CXType, - length: u32, - index: u32, -} - -impl Iterator for TypeTemplateArgIterator { - type Item = Type; - fn next(&mut self) -> Option { - if self.index < self.length { - let idx = self.index as c_uint; - self.index += 1; - Some(Type { - x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) }, - }) - } else { - None - } - } -} - -impl ExactSizeIterator for TypeTemplateArgIterator { - fn len(&self) -> usize { - assert!(self.index <= self.length); - (self.length - self.index) as usize - } -} - -/// A `SourceLocation` is a file, line, column, and byte offset location for -/// some source text. -pub struct SourceLocation { - x: CXSourceLocation, -} - -impl SourceLocation { - /// Get the (file, line, column, byte offset) tuple for this source - /// location. - pub fn location(&self) -> (File, usize, usize, usize) { - unsafe { - let mut file = mem::zeroed(); - let mut line = 0; - let mut col = 0; - let mut off = 0; - clang_getSpellingLocation( - self.x, &mut file, &mut line, &mut col, &mut off, - ); - (File { x: file }, line as usize, col as usize, off as usize) - } - } -} - -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) - } else { - "builtin definitions".fmt(f) - } - } -} - -impl fmt::Debug for SourceLocation { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) - } -} - -/// A comment in the source text. -/// -/// Comments are sort of parsed by Clang, and have a tree structure. -pub struct Comment { - x: CXComment, -} - -impl Comment { - /// What kind of comment is this? - pub fn kind(&self) -> CXCommentKind { - unsafe { clang_Comment_getKind(self.x) } - } - - /// Get this comment's children comment - pub fn get_children(&self) -> CommentChildrenIterator { - CommentChildrenIterator { - parent: self.x, - length: unsafe { clang_Comment_getNumChildren(self.x) }, - index: 0, - } - } - - /// Given that this comment is the start or end of an HTML tag, get its tag - /// name. - pub fn get_tag_name(&self) -> String { - unsafe { cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) } - } - - /// Given that this comment is an HTML start tag, get its attributes. - pub fn get_tag_attrs(&self) -> CommentAttributesIterator { - CommentAttributesIterator { - x: self.x, - length: unsafe { clang_HTMLStartTag_getNumAttrs(self.x) }, - index: 0, - } - } -} - -/// An iterator for a comment's children -pub struct CommentChildrenIterator { - parent: CXComment, - length: c_uint, - index: c_uint, -} - -impl Iterator for CommentChildrenIterator { - type Item = Comment; - fn next(&mut self) -> Option { - if self.index < self.length { - let idx = self.index; - self.index += 1; - Some(Comment { - x: unsafe { clang_Comment_getChild(self.parent, idx) }, - }) - } else { - None - } - } -} - -/// An HTML start tag comment attribute -pub struct CommentAttribute { - /// HTML start tag attribute name - pub name: String, - /// HTML start tag attribute value - pub value: String, -} - -/// An iterator for a comment's attributes -pub struct CommentAttributesIterator { - x: CXComment, - length: c_uint, - index: c_uint, -} - -impl Iterator for CommentAttributesIterator { - type Item = CommentAttribute; - fn next(&mut self) -> Option { - if self.index < self.length { - let idx = self.index; - self.index += 1; - Some(CommentAttribute { - name: unsafe { - cxstring_into_string(clang_HTMLStartTag_getAttrName( - self.x, idx, - )) - }, - value: unsafe { - cxstring_into_string(clang_HTMLStartTag_getAttrValue( - self.x, idx, - )) - }, - }) - } else { - None - } - } -} - -/// A source file. -pub struct File { - x: CXFile, -} - -impl File { - /// Get the name of this source file. - pub fn name(&self) -> Option { - if self.x.is_null() { - return None; - } - Some(unsafe { cxstring_into_string(clang_getFileName(self.x)) }) - } -} - -fn cxstring_to_string_leaky(s: CXString) -> String { - if s.data.is_null() { - return "".to_owned(); - } - let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) }; - c_str.to_string_lossy().into_owned() -} - -fn cxstring_into_string(s: CXString) -> String { - let ret = cxstring_to_string_leaky(s); - unsafe { clang_disposeString(s) }; - ret -} - -/// An `Index` is an environment for a set of translation units that will -/// typically end up linked together in one final binary. -pub struct Index { - x: CXIndex, -} - -impl Index { - /// Construct a new `Index`. - /// - /// The `pch` parameter controls whether declarations in pre-compiled - /// headers are included when enumerating a translation unit's "locals". - /// - /// The `diag` parameter controls whether debugging diagnostics are enabled. - pub fn new(pch: bool, diag: bool) -> Index { - unsafe { - Index { - x: clang_createIndex(pch as c_int, diag as c_int), - } - } - } -} - -impl fmt::Debug for Index { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Index {{ }}") - } -} - -impl Drop for Index { - fn drop(&mut self) { - unsafe { - clang_disposeIndex(self.x); - } - } -} - -/// A translation unit (or "compilation unit"). -pub struct TranslationUnit { - x: CXTranslationUnit, -} - -impl fmt::Debug for TranslationUnit { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "TranslationUnit {{ }}") - } -} - -impl TranslationUnit { - /// Parse a source file into a translation unit. - pub fn parse( - ix: &Index, - file: &str, - cmd_args: &[String], - unsaved: &[UnsavedFile], - opts: CXTranslationUnit_Flags, - ) -> Option { - let fname = CString::new(file).unwrap(); - let _c_args: Vec = cmd_args - .iter() - .map(|s| CString::new(s.clone()).unwrap()) - .collect(); - let c_args: Vec<*const c_char> = - _c_args.iter().map(|s| s.as_ptr()).collect(); - let mut c_unsaved: Vec = - unsaved.iter().map(|f| f.x).collect(); - let tu = unsafe { - clang_parseTranslationUnit( - ix.x, - fname.as_ptr(), - c_args.as_ptr(), - c_args.len() as c_int, - c_unsaved.as_mut_ptr(), - c_unsaved.len() as c_uint, - opts, - ) - }; - if tu.is_null() { - None - } else { - Some(TranslationUnit { x: tu }) - } - } - - /// Get the Clang diagnostic information associated with this translation - /// unit. - pub fn diags(&self) -> Vec { - unsafe { - let num = clang_getNumDiagnostics(self.x) as usize; - let mut diags = vec![]; - for i in 0..num { - diags.push(Diagnostic { - x: clang_getDiagnostic(self.x, i as c_uint), - }); - } - diags - } - } - - /// Get a cursor pointing to the root of this translation unit's AST. - pub fn cursor(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getTranslationUnitCursor(self.x), - } - } - } - - /// Is this the null translation unit? - pub fn is_null(&self) -> bool { - self.x.is_null() - } -} - -impl Drop for TranslationUnit { - fn drop(&mut self) { - unsafe { - clang_disposeTranslationUnit(self.x); - } - } -} - -/// A diagnostic message generated while parsing a translation unit. -pub struct Diagnostic { - x: CXDiagnostic, -} - -impl Diagnostic { - /// Format this diagnostic message as a string, using the given option bit - /// flags. - pub fn format(&self) -> String { - unsafe { - let opts = clang_defaultDiagnosticDisplayOptions(); - cxstring_into_string(clang_formatDiagnostic(self.x, opts)) - } - } - - /// What is the severity of this diagnostic message? - pub fn severity(&self) -> CXDiagnosticSeverity { - unsafe { clang_getDiagnosticSeverity(self.x) } - } -} - -impl Drop for Diagnostic { - /// Destroy this diagnostic message. - fn drop(&mut self) { - unsafe { - clang_disposeDiagnostic(self.x); - } - } -} - -/// A file which has not been saved to disk. -pub struct UnsavedFile { - x: CXUnsavedFile, - /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in - /// `CXUnsavedFile`. - pub name: CString, - contents: CString, -} - -impl UnsavedFile { - /// Construct a new unsaved file with the given `name` and `contents`. - pub fn new(name: &str, contents: &str) -> UnsavedFile { - let name = CString::new(name).unwrap(); - let contents = CString::new(contents).unwrap(); - let x = CXUnsavedFile { - Filename: name.as_ptr(), - Contents: contents.as_ptr(), - Length: contents.as_bytes().len() as c_ulong, - }; - UnsavedFile { x, name, contents } - } -} - -impl fmt::Debug for UnsavedFile { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!( - fmt, - "UnsavedFile(name: {:?}, contents: {:?})", - self.name, self.contents - ) - } -} - -/// Convert a cursor kind into a static string. -pub fn kind_to_str(x: CXCursorKind) -> String { - unsafe { cxstring_into_string(clang_getCursorKindSpelling(x)) } -} - -/// Convert a type kind to a static string. -pub fn type_to_str(x: CXTypeKind) -> String { - unsafe { cxstring_into_string(clang_getTypeKindSpelling(x)) } -} - -/// Dump the Clang AST to stdout for debugging purposes. -pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { - fn print_indent>(depth: isize, s: S) { - for _ in 0..depth { - print!(" "); - } - println!("{}", s.as_ref()); - } - - fn print_cursor>(depth: isize, prefix: S, c: &Cursor) { - let prefix = prefix.as_ref(); - print_indent( - depth, - format!(" {}kind = {}", prefix, kind_to_str(c.kind())), - ); - print_indent( - depth, - format!(" {}spelling = \"{}\"", prefix, c.spelling()), - ); - print_indent(depth, format!(" {}location = {}", prefix, c.location())); - print_indent( - depth, - format!(" {}is-definition? {}", prefix, c.is_definition()), - ); - print_indent( - depth, - format!(" {}is-declaration? {}", prefix, c.is_declaration()), - ); - print_indent( - depth, - format!( - " {}is-inlined-function? {}", - prefix, - c.is_inlined_function() - ), - ); - - let templ_kind = c.template_kind(); - if templ_kind != CXCursor_NoDeclFound { - print_indent( - depth, - format!( - " {}template-kind = {}", - prefix, - kind_to_str(templ_kind) - ), - ); - } - if let Some(usr) = c.usr() { - print_indent(depth, format!(" {}usr = \"{}\"", prefix, usr)); - } - if let Ok(num) = c.num_args() { - print_indent(depth, format!(" {}number-of-args = {}", prefix, num)); - } - if let Some(num) = c.num_template_args() { - print_indent( - depth, - format!(" {}number-of-template-args = {}", prefix, num), - ); - } - if let Some(width) = c.bit_width() { - print_indent(depth, format!(" {}bit-width = {}", prefix, width)); - } - if let Some(ty) = c.enum_type() { - print_indent( - depth, - format!(" {}enum-type = {}", prefix, type_to_str(ty.kind())), - ); - } - if let Some(val) = c.enum_val_signed() { - print_indent(depth, format!(" {}enum-val = {}", prefix, val)); - } - if let Some(ty) = c.typedef_type() { - print_indent( - depth, - format!(" {}typedef-type = {}", prefix, type_to_str(ty.kind())), - ); - } - if let Some(ty) = c.ret_type() { - print_indent( - depth, - format!(" {}ret-type = {}", prefix, type_to_str(ty.kind())), - ); - } - - if let Some(refd) = c.referenced() { - if refd != *c { - println!(); - print_cursor( - depth, - String::from(prefix) + "referenced.", - &refd, - ); - } - } - - let canonical = c.canonical(); - if canonical != *c { - println!(); - print_cursor( - depth, - String::from(prefix) + "canonical.", - &canonical, - ); - } - - if let Some(specialized) = c.specialized() { - if specialized != *c { - println!(); - print_cursor( - depth, - String::from(prefix) + "specialized.", - &specialized, - ); - } - } - - if let Some(parent) = c.fallible_semantic_parent() { - println!(); - print_cursor( - depth, - String::from(prefix) + "semantic-parent.", - &parent, - ); - } - } - - fn print_type>(depth: isize, prefix: S, ty: &Type) { - let prefix = prefix.as_ref(); - - let kind = ty.kind(); - print_indent(depth, format!(" {}kind = {}", prefix, type_to_str(kind))); - if kind == CXType_Invalid { - return; - } - - print_indent(depth, format!(" {}cconv = {}", prefix, ty.call_conv())); - - print_indent( - depth, - format!(" {}spelling = \"{}\"", prefix, ty.spelling()), - ); - let num_template_args = - unsafe { clang_Type_getNumTemplateArguments(ty.x) }; - if num_template_args >= 0 { - print_indent( - depth, - format!( - " {}number-of-template-args = {}", - prefix, num_template_args - ), - ); - } - if let Some(num) = ty.num_elements() { - print_indent( - depth, - format!(" {}number-of-elements = {}", prefix, num), - ); - } - print_indent( - depth, - format!(" {}is-variadic? {}", prefix, ty.is_variadic()), - ); - - let canonical = ty.canonical_type(); - if canonical != *ty { - println!(); - print_type(depth, String::from(prefix) + "canonical.", &canonical); - } - - if let Some(pointee) = ty.pointee_type() { - if pointee != *ty { - println!(); - print_type(depth, String::from(prefix) + "pointee.", &pointee); - } - } - - if let Some(elem) = ty.elem_type() { - if elem != *ty { - println!(); - print_type(depth, String::from(prefix) + "elements.", &elem); - } - } - - if let Some(ret) = ty.ret_type() { - if ret != *ty { - println!(); - print_type(depth, String::from(prefix) + "return.", &ret); - } - } - - let named = ty.named(); - if named != *ty && named.is_valid() { - println!(); - print_type(depth, String::from(prefix) + "named.", &named); - } - } - - print_indent(depth, "("); - print_cursor(depth, "", c); - - println!(); - let ty = c.cur_type(); - print_type(depth, "type.", &ty); - - let declaration = ty.declaration(); - if declaration != *c && declaration.kind() != CXCursor_NoDeclFound { - println!(); - print_cursor(depth, "type.declaration.", &declaration); - } - - // Recurse. - let mut found_children = false; - c.visit(|s| { - if !found_children { - println!(); - found_children = true; - } - ast_dump(&s, depth + 1) - }); - - print_indent(depth, ")"); - - CXChildVisit_Continue -} - -/// Try to extract the clang version to a string -pub fn extract_clang_version() -> String { - unsafe { cxstring_into_string(clang_getClangVersion()) } -} - -/// A wrapper for the result of evaluating an expression. -#[derive(Debug)] -pub struct EvalResult { - x: CXEvalResult, -} - -impl EvalResult { - /// Evaluate `cursor` and return the result. - pub fn new(cursor: Cursor) -> Option { - // Work around https://bugs.llvm.org/show_bug.cgi?id=42532, see: - // * https://github.com/rust-lang/rust-bindgen/issues/283 - // * https://github.com/rust-lang/rust-bindgen/issues/1590 - { - let mut found_cant_eval = false; - cursor.visit(|c| { - if c.kind() == CXCursor_TypeRef && - c.cur_type().canonical_type().kind() == CXType_Unexposed - { - found_cant_eval = true; - return CXChildVisit_Break; - } - - CXChildVisit_Recurse - }); - - if found_cant_eval { - return None; - } - } - Some(EvalResult { - x: unsafe { clang_Cursor_Evaluate(cursor.x) }, - }) - } - - fn kind(&self) -> CXEvalResultKind { - unsafe { clang_EvalResult_getKind(self.x) } - } - - /// Try to get back the result as a double. - pub fn as_double(&self) -> Option { - match self.kind() { - CXEval_Float => { - Some(unsafe { clang_EvalResult_getAsDouble(self.x) } as f64) - } - _ => None, - } - } - - /// Try to get back the result as an integer. - pub fn as_int(&self) -> Option { - if self.kind() != CXEval_Int { - return None; - } - - if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 { - let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) }; - if value > i64::max_value() as c_ulonglong { - return None; - } - - return Some(value as i64); - } - - let value = unsafe { clang_EvalResult_getAsLongLong(self.x) }; - if value > i64::max_value() as c_longlong { - return None; - } - if value < i64::min_value() as c_longlong { - return None; - } - Some(value as i64) - } - - /// Evaluates the expression as a literal string, that may or may not be - /// valid utf-8. - pub fn as_literal_string(&self) -> Option> { - match self.kind() { - CXEval_StrLiteral => { - let ret = unsafe { - CStr::from_ptr(clang_EvalResult_getAsStr(self.x)) - }; - Some(ret.to_bytes().to_vec()) - } - _ => None, - } - } -} - -impl Drop for EvalResult { - fn drop(&mut self) { - unsafe { clang_EvalResult_dispose(self.x) }; - } -} - -/// Target information obtained from libclang. -#[derive(Debug)] -pub struct TargetInfo { - /// The target triple. - pub triple: String, - /// The width of the pointer _in bits_. - pub pointer_width: usize, -} - -impl TargetInfo { - /// Tries to obtain target information from libclang. - pub fn new(tu: &TranslationUnit) -> Option { - if !clang_getTranslationUnitTargetInfo::is_loaded() { - return None; - } - let triple; - let pointer_width; - unsafe { - let ti = clang_getTranslationUnitTargetInfo(tu.x); - triple = cxstring_into_string(clang_TargetInfo_getTriple(ti)); - pointer_width = clang_TargetInfo_getPointerWidth(ti); - clang_TargetInfo_dispose(ti); - } - assert!(pointer_width > 0); - assert_eq!(pointer_width % 8, 0); - Some(TargetInfo { - triple, - pointer_width: pointer_width as usize, - }) - } -} diff --git a/src/codegen/bitfield_unit.rs b/src/codegen/bitfield_unit.rs deleted file mode 100644 index 73ec2bd629..0000000000 --- a/src/codegen/bitfield_unit.rs +++ /dev/null @@ -1,102 +0,0 @@ -#[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] - 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); - } - } -} diff --git a/src/codegen/dyngen.rs b/src/codegen/dyngen.rs deleted file mode 100644 index 71c4dab1dc..0000000000 --- a/src/codegen/dyngen.rs +++ /dev/null @@ -1,178 +0,0 @@ -use crate::codegen; -use crate::ir::function::Abi; -use proc_macro2::Ident; - -/// Used to build the output tokens for dynamic bindings. -#[derive(Default)] -pub struct DynamicItems { - /// Tracks the tokens that will appears inside the library struct -- e.g.: - /// ```ignore - /// struct Lib { - /// __library: ::libloading::Library, - /// pub x: Result, // <- tracks these - /// ... - /// } - /// ``` - struct_members: Vec, - - /// Tracks the tokens that will appear inside the library struct's implementation, e.g.: - /// - /// ```ignore - /// impl Lib { - /// ... - /// pub unsafe fn foo(&self, ...) { // <- tracks these - /// ... - /// } - /// } - /// ``` - struct_implementation: Vec, - - /// Tracks the initialization of the fields inside the `::new` constructor of the library - /// struct, e.g.: - /// ```ignore - /// impl Lib { - /// - /// pub unsafe fn new

(path: P) -> Result - /// where - /// P: AsRef<::std::ffi::OsStr>, - /// { - /// ... - /// let foo = __library.get(...) ...; // <- tracks these - /// ... - /// } - /// - /// ... - /// } - /// ``` - constructor_inits: Vec, - - /// Tracks the information that is passed to the library struct at the end of the `::new` - /// constructor, e.g.: - /// ```ignore - /// impl LibFoo { - /// pub unsafe fn new

(path: P) -> Result - /// where - /// P: AsRef<::std::ffi::OsStr>, - /// { - /// ... - /// Ok(LibFoo { - /// __library: __library, - /// foo, - /// bar, // <- tracks these - /// ... - /// }) - /// } - /// } - /// ``` - init_fields: Vec, -} - -impl DynamicItems { - pub fn new() -> Self { - Self::default() - } - - pub fn get_tokens(&self, lib_ident: Ident) -> proc_macro2::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; - - quote! { - extern crate libloading; - - pub struct #lib_ident { - __library: ::libloading::Library, - #(#struct_members)* - } - - impl #lib_ident { - pub unsafe fn new

( - path: P - ) -> Result - where P: AsRef<::std::ffi::OsStr> { - let library = ::libloading::Library::new(path)?; - Self::from_library(library) - } - - pub unsafe fn from_library( - library: L - ) -> Result - where L: Into<::libloading::Library> { - let __library = library.into(); - #( #constructor_inits )* - Ok(#lib_ident { - __library, - #( #init_fields ),* - }) - } - - #( #struct_implementation )* - } - } - } - - pub fn push( - &mut self, - ident: Ident, - abi: Abi, - is_variadic: bool, - is_required: bool, - args: Vec, - args_identifiers: Vec, - ret: proc_macro2::TokenStream, - ret_ty: proc_macro2::TokenStream, - ) { - if !is_variadic { - assert_eq!(args.len(), args_identifiers.len()); - } - - let signature = quote! { unsafe extern #abi fn ( #( #args),* ) #ret }; - let member = if is_required { - signature - } else { - quote! { Result<#signature, ::libloading::Error> } - }; - - self.struct_members.push(quote! { - pub #ident: #member, - }); - - // N.B: If the signature was required, it won't be wrapped in a Result<...> - // and we can simply call it directly. - let fn_ = if is_required { - quote! { self.#ident } - } else { - quote! { self.#ident.as_ref().expect("Expected function, got error.") } - }; - let call_body = quote! { - (#fn_)(#( #args_identifiers ),*) - }; - - // We can't implement variadic functions from C easily, so we allow to - // access the function pointer so that the user can call it just fine. - if !is_variadic { - self.struct_implementation.push(quote! { - pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { - #call_body - } - }); - } - - // 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()); - self.constructor_inits.push(if is_required { - quote! { - let #ident = __library.get(#ident_str).map(|sym| *sym)?; - } - } else { - quote! { - let #ident = __library.get(#ident_str).map(|sym| *sym); - } - }); - - self.init_fields.push(quote! { - #ident - }); - } -} diff --git a/src/codegen/error.rs b/src/codegen/error.rs deleted file mode 100644 index c1bcf4e1cb..0000000000 --- a/src/codegen/error.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::error; -use std::fmt; - -/// Errors that can occur during code generation. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Error { - /// Tried to generate an opaque blob for a type that did not have a layout. - NoLayoutForOpaqueBlob, - - /// Tried to instantiate an opaque template definition, or a template - /// definition that is too difficult for us to understand (like a partial - /// template specialization). - InstantiationOfOpaqueType, -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(match *self { - Error::NoLayoutForOpaqueBlob => { - "Tried to generate an opaque blob, but had no layout" - } - Error::InstantiationOfOpaqueType => { - "Instantiation of opaque template type or partial template \ - specialization" - } - }) - } -} - -impl error::Error for Error {} - -/// A `Result` of `T` or an error of `bindgen::codegen::error::Error`. -pub type Result = ::std::result::Result; diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs deleted file mode 100644 index 75c169c67d..0000000000 --- a/src/codegen/helpers.rs +++ /dev/null @@ -1,299 +0,0 @@ -//! Helpers for code generation that don't need macro expansion. - -use crate::ir::context::BindgenContext; -use crate::ir::layout::Layout; -use proc_macro2::{Ident, Span, TokenStream}; -use quote::TokenStreamExt; - -pub mod attributes { - use proc_macro2::{Ident, Span, TokenStream}; - use std::str::FromStr; - - pub fn repr(which: &str) -> TokenStream { - let which = Ident::new(which, Span::call_site()); - quote! { - #[repr( #which )] - } - } - - pub 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 ),* )] - } - } - - pub 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 ),* )] - } - } - - pub fn inline() -> TokenStream { - quote! { - #[inline] - } - } - - pub fn must_use() -> TokenStream { - quote! { - #[must_use] - } - } - - pub fn non_exhaustive() -> TokenStream { - quote! { - #[non_exhaustive] - } - } - - pub fn doc(comment: String) -> TokenStream { - // NOTE(emilio): By this point comments are already preprocessed and in - // `///` form. Quote turns them into `#[doc]` comments, but oh well. - TokenStream::from_str(&comment).unwrap() - } - - pub fn link_name(name: &str) -> TokenStream { - // LLVM mangles the name by default but it's already mangled. - // Prefixing the name with \u{1} should tell LLVM to not mangle it. - let name = format!("\u{1}{}", name); - quote! { - #[link_name = #name] - } - } -} - -/// 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 fn blob(ctx: &BindgenContext, layout: Layout) -> TokenStream { - 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_name = match opaque.known_rust_type_for_array(ctx) { - Some(ty) => ty, - None => { - warn!("Found unknown alignment on code generation!"); - "u8" - } - }; - - let ty_name = Ident::new(ty_name, Span::call_site()); - - let data_len = opaque.array_size(ctx).unwrap_or(layout.size); - - if data_len == 1 { - quote! { - #ty_name - } - } else { - quote! { - [ #ty_name ; #data_len ] - } - } -} - -/// Integer type of the same size as the given `Layout`. -pub fn integer_type( - ctx: &BindgenContext, - layout: Layout, -) -> Option { - let name = Layout::known_type_for_size(ctx, layout.size)?; - let name = Ident::new(name, Span::call_site()); - Some(quote! { #name }) -} - -/// Generates a bitfield allocation unit type for a type with the given `Layout`. -pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> TokenStream { - let mut tokens = quote! {}; - - if ctx.options().enable_cxx_namespaces { - tokens.append_all(quote! { root:: }); - } - - let size = layout.size; - tokens.append_all(quote! { - __BindgenBitfieldUnit<[u8; #size]> - }); - - tokens -} - -pub mod ast_ty { - use crate::ir::context::BindgenContext; - use crate::ir::function::FunctionSig; - use crate::ir::layout::Layout; - use crate::ir::ty::FloatKind; - use proc_macro2::{self, TokenStream}; - use std::str::FromStr; - - pub fn c_void(ctx: &BindgenContext) -> TokenStream { - // ctypes_prefix takes precedence - match ctx.options().ctypes_prefix { - Some(ref prefix) => { - let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); - quote! { - #prefix::c_void - } - } - None => { - if ctx.options().use_core && - ctx.options().rust_features.core_ffi_c_void - { - quote! { ::core::ffi::c_void } - } else { - quote! { ::std::os::raw::c_void } - } - } - } - } - - pub fn raw_type(ctx: &BindgenContext, name: &str) -> TokenStream { - let ident = ctx.rust_ident_raw(name); - match ctx.options().ctypes_prefix { - Some(ref prefix) => { - let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); - quote! { - #prefix::#ident - } - } - None => quote! { - ::std::os::raw::#ident - }, - } - } - - pub fn float_kind_rust_type( - ctx: &BindgenContext, - fk: FloatKind, - layout: Option, - ) -> TokenStream { - // TODO: we probably should take the type layout into account more - // often? - // - // Also, maybe this one shouldn't be the default? - match (fk, ctx.options().convert_floats) { - (FloatKind::Float, true) => quote! { f32 }, - (FloatKind::Double, true) => quote! { f64 }, - (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 => quote! { f32 }, - 8 => quote! { f64 }, - // TODO(emilio): If rust ever gains f128 we should - // use it here and below. - _ => super::integer_type(ctx, layout) - .unwrap_or(quote! { f64 }), - } - } - None => { - debug_assert!( - false, - "How didn't we know the layout for a primitive type?" - ); - quote! { f64 } - } - } - } - (FloatKind::Float128, _) => { - if ctx.options().rust_features.i128_and_u128 { - quote! { u128 } - } else { - quote! { [u64; 2] } - } - } - } - } - - pub fn int_expr(val: i64) -> TokenStream { - // Don't use quote! { #val } because that adds the type suffix. - let val = proc_macro2::Literal::i64_unsuffixed(val); - quote!(#val) - } - - pub fn uint_expr(val: u64) -> TokenStream { - // Don't use quote! { #val } because that adds the type suffix. - let val = proc_macro2::Literal::u64_unsuffixed(val); - quote!(#val) - } - - pub fn byte_array_expr(bytes: &[u8]) -> TokenStream { - let mut bytes: Vec<_> = bytes.to_vec(); - bytes.push(0); - quote! { [ #(#bytes),* ] } - } - - pub fn cstr_expr(mut string: String) -> TokenStream { - string.push('\0'); - let b = proc_macro2::Literal::byte_string(string.as_bytes()); - quote! { - #b - } - } - - pub fn float_expr(ctx: &BindgenContext, f: f64) -> Result { - if f.is_finite() { - let val = proc_macro2::Literal::f64_unsuffixed(f); - - return Ok(quote!(#val)); - } - - let prefix = ctx.trait_prefix(); - - if f.is_nan() { - return Ok(quote! { - ::#prefix::f64::NAN - }); - } - - if f.is_infinite() { - return Ok(if f.is_sign_positive() { - quote! { - ::#prefix::f64::INFINITY - } - } else { - quote! { - ::#prefix::f64::NEG_INFINITY - } - }); - } - - warn!("Unknown non-finite float number: {:?}", f); - Err(()) - } - - pub fn arguments_from_signature( - signature: &FunctionSig, - ctx: &BindgenContext, - ) -> Vec { - let mut unnamed_arguments = 0; - signature - .argument_types() - .iter() - .map(|&(ref name, _ty)| match *name { - Some(ref name) => { - let name = ctx.rust_ident(name); - quote! { #name } - } - None => { - unnamed_arguments += 1; - let name = - ctx.rust_ident(format!("arg{}", unnamed_arguments)); - quote! { #name } - } - }) - .collect() - } -} diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs deleted file mode 100644 index 0e2cd33ad5..0000000000 --- a/src/codegen/impl_debug.rs +++ /dev/null @@ -1,245 +0,0 @@ -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}; - -pub fn gen_debug_impl( - ctx: &BindgenContext, - fields: &[Field], - item: &Item, - kind: CompKind, -) -> proc_macro2::TokenStream { - let struct_name = item.canonical_name(ctx); - let mut format_string = format!("{} {{{{ ", struct_name); - let mut tokens = vec![]; - - if item.is_opaque(ctx, &()) { - format_string.push_str("opaque"); - } else { - match kind { - CompKind::Union => { - format_string.push_str("union"); - } - CompKind::Struct => { - let processed_fields = fields.iter().filter_map(|f| match f { - Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), - Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), - }); - - for (i, (fstring, toks)) in processed_fields.enumerate() { - if i > 0 { - format_string.push_str(", "); - } - tokens.extend(toks); - format_string.push_str(&fstring); - } - } - } - } - - format_string.push_str(" }}"); - tokens.insert(0, quote! { #format_string }); - - let prefix = ctx.trait_prefix(); - - quote! { - fn fmt(&self, f: &mut ::#prefix::fmt::Formatter<'_>) -> ::#prefix ::fmt::Result { - write!(f, #( #tokens ),*) - } - } -} - -/// A trait for the things which we can codegen tokens that contribute towards a -/// generated `impl Debug`. -pub trait ImplDebug<'a> { - /// Any extra parameter required by this a particular `ImplDebug` implementation. - type Extra; - - /// Generate a format string snippet to be included in the larger `impl Debug` - /// format string, and the code to get the format string's interpolation values. - fn impl_debug( - &self, - ctx: &BindgenContext, - extra: Self::Extra, - ) -> Option<(String, Vec)>; -} - -impl<'a> ImplDebug<'a> for FieldData { - type Extra = (); - - fn impl_debug( - &self, - ctx: &BindgenContext, - _: Self::Extra, - ) -> Option<(String, Vec)> { - if let Some(name) = self.name() { - ctx.resolve_item(self.ty()).impl_debug(ctx, name) - } else { - None - } - } -} - -impl<'a> ImplDebug<'a> for BitfieldUnit { - type Extra = (); - - fn impl_debug( - &self, - ctx: &BindgenContext, - _: Self::Extra, - ) -> Option<(String, Vec)> { - let mut format_string = String::new(); - let mut tokens = vec![]; - for (i, bitfield) in self.bitfields().iter().enumerate() { - if i > 0 { - format_string.push_str(", "); - } - - if let Some(bitfield_name) = bitfield.name() { - format_string.push_str(&format!("{} : {{:?}}", bitfield_name)); - let getter_name = bitfield.getter_name(); - let name_ident = ctx.rust_ident_raw(getter_name); - tokens.push(quote! { - self.#name_ident () - }); - } - } - - Some((format_string, tokens)) - } -} - -impl<'a> ImplDebug<'a> for Item { - type Extra = &'a str; - - fn impl_debug( - &self, - ctx: &BindgenContext, - name: &str, - ) -> Option<(String, Vec)> { - let name_ident = ctx.rust_ident(name); - - // We don't know if blocklisted items `impl Debug` or not, so we can't - // add them to the format string we're building up. - if !ctx.allowlisted_items().contains(&self.id()) { - return None; - } - - let ty = match self.as_type() { - Some(ty) => ty, - None => { - return None; - } - }; - - fn debug_print( - name: &str, - name_ident: proc_macro2::TokenStream, - ) -> Option<(String, Vec)> { - Some(( - format!("{}: {{:?}}", name), - vec![quote! { - self.#name_ident - }], - )) - } - - match *ty.kind() { - // Handle the simple cases. - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Function(..) | - TypeKind::Enum(..) | - TypeKind::Reference(..) | - TypeKind::UnresolvedTypeRef(..) | - TypeKind::ObjCInterface(..) | - TypeKind::ObjCId | - TypeKind::Comp(..) | - TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }), - - TypeKind::TemplateInstantiation(ref inst) => { - if inst.is_opaque(ctx, self) { - Some((format!("{}: opaque", name), vec![])) - } else { - debug_print(name, quote! { #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![])) - } - - 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![])) - } 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::() - }], - )) - } - } - 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![])) - } else { - let self_ids = 0..len; - Some(( - format!("{}({{}})", name), - vec![quote! { - #(format!("{:?}", self.#self_ids)),* - }], - )) - } - } - - TypeKind::ResolvedTypeRef(t) | - TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) | - TypeKind::BlockPointer(t) => { - // We follow the aliases - ctx.resolve_item(t).impl_debug(ctx, name) - } - - TypeKind::Pointer(inner) => { - let inner_type = ctx.resolve_type(inner).canonical_type(ctx); - match *inner_type.kind() { - TypeKind::Function(ref sig) - if !sig.function_pointers_can_derive() => - { - Some((format!("{}: FunctionPointer", name), vec![])) - } - _ => debug_print(name, quote! { #name_ident }), - } - } - - TypeKind::Opaque => None, - } - } -} diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs deleted file mode 100644 index 960306ffc6..0000000000 --- a/src/codegen/impl_partialeq.rs +++ /dev/null @@ -1,142 +0,0 @@ -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}; - -/// Generate a manual implementation of `PartialEq` trait for the -/// specified compound type. -pub fn gen_partialeq_impl( - ctx: &BindgenContext, - comp_info: &CompInfo, - item: &Item, - ty_for_impl: &proc_macro2::TokenStream, -) -> Option { - let mut tokens = vec![]; - - if item.is_opaque(ctx, &()) { - tokens.push(quote! { - &self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..] - }); - } else if comp_info.kind() == CompKind::Union { - assert!(!ctx.options().rust_features().untagged_union); - tokens.push(quote! { - &self.bindgen_union_field[..] == &other.bindgen_union_field[..] - }); - } else { - for base in comp_info.base_members().iter() { - 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)); - } - } - - for field in comp_info.fields() { - match *field { - Field::DataMember(ref fd) => { - let ty_item = ctx.resolve_item(fd.ty()); - let name = fd.name().unwrap(); - tokens.push(gen_field(ctx, ty_item, name)); - } - Field::Bitfields(ref bu) => { - for bitfield in bu.bitfields() { - if bitfield.name().is_some() { - let getter_name = bitfield.getter_name(); - let name_ident = ctx.rust_ident_raw(getter_name); - tokens.push(quote! { - self.#name_ident () == other.#name_ident () - }); - } - } - } - } - } - } - - Some(quote! { - fn eq(&self, other: & #ty_for_impl) -> bool { - #( #tokens )&&* - } - }) -} - -fn gen_field( - ctx: &BindgenContext, - ty_item: &Item, - name: &str, -) -> proc_macro2::TokenStream { - fn quote_equals( - name_ident: proc_macro2::Ident, - ) -> proc_macro2::TokenStream { - quote! { self.#name_ident == other.#name_ident } - } - - let name_ident = ctx.rust_ident(name); - let ty = ty_item.expect_type(); - - match *ty.kind() { - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Complex(..) | - TypeKind::Float(..) | - TypeKind::Enum(..) | - TypeKind::TypeParam | - TypeKind::UnresolvedTypeRef(..) | - TypeKind::Reference(..) | - TypeKind::ObjCInterface(..) | - TypeKind::ObjCId | - TypeKind::ObjCSel | - 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::Vector(_, len) => { - let self_ids = 0..len; - let other_ids = 0..len; - quote! { - #(self.#self_ids == other.#other_ids &&)* true - } - } - - TypeKind::ResolvedTypeRef(t) | - TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) | - TypeKind::BlockPointer(t) => { - let inner_item = ctx.resolve_item(t); - gen_field(ctx, inner_item, name) - } - } -} diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs deleted file mode 100644 index ffb21d13b3..0000000000 --- a/src/codegen/mod.rs +++ /dev/null @@ -1,4874 +0,0 @@ -mod dyngen; -mod error; -mod helpers; -mod impl_debug; -mod impl_partialeq; -pub mod struct_layout; - -#[cfg(test)] -#[allow(warnings)] -pub(crate) mod bitfield_unit; -#[cfg(all(test, target_endian = "little"))] -mod bitfield_unit_tests; - -use self::dyngen::DynamicItems; -use self::helpers::attributes; -use self::struct_layout::StructLayoutTracker; - -use super::BindgenOptions; - -use crate::ir::analysis::{HasVtable, Sizedness}; -use crate::ir::annotations::FieldAccessorKind; -use crate::ir::comment; -use crate::ir::comp::{ - Bitfield, BitfieldUnit, CompInfo, CompKind, Field, FieldData, FieldMethods, - Method, MethodKind, -}; -use crate::ir::context::{BindgenContext, ItemId}; -use crate::ir::derive::{ - CanDerive, CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq, - CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd, -}; -use crate::ir::dot; -use crate::ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; -use crate::ir::function::{Abi, Function, FunctionKind, FunctionSig, Linkage}; -use crate::ir::int::IntKind; -use crate::ir::item::{IsOpaque, Item, ItemCanonicalName, ItemCanonicalPath}; -use crate::ir::item_kind::ItemKind; -use crate::ir::layout::Layout; -use crate::ir::module::Module; -use crate::ir::objc::{ObjCInterface, ObjCMethod}; -use crate::ir::template::{ - AsTemplateParam, TemplateInstantiation, TemplateParameters, -}; -use crate::ir::ty::{Type, TypeKind}; -use crate::ir::var::Var; - -use proc_macro2::{self, Ident, Span}; -use quote::TokenStreamExt; - -use crate::{Entry, HashMap, HashSet}; -use std::borrow::Cow; -use std::cell::Cell; -use std::collections::VecDeque; -use std::fmt::Write; -use std::iter; -use std::ops; -use std::str::FromStr; - -// Name of type defined in constified enum module -pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type"; - -fn top_level_path( - ctx: &BindgenContext, - item: &Item, -) -> Vec { - let mut path = vec![quote! { self }]; - - if ctx.options().enable_cxx_namespaces { - for _ in 0..item.codegen_depth(ctx) { - path.push(quote! { super }); - } - } - - path -} - -fn root_import( - ctx: &BindgenContext, - module: &Item, -) -> proc_macro2::TokenStream { - assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up"); - assert!(module.is_module()); - - let mut path = top_level_path(ctx, module); - - let root = ctx.root_module().canonical_name(ctx); - let root_ident = ctx.rust_ident(&root); - path.push(quote! { #root_ident }); - - let mut tokens = quote! {}; - tokens.append_separated(path, quote!(::)); - - quote! { - #[allow(unused_imports)] - use #tokens ; - } -} - -bitflags! { - struct DerivableTraits: u16 { - const DEBUG = 1 << 0; - const DEFAULT = 1 << 1; - const COPY = 1 << 2; - const CLONE = 1 << 3; - const HASH = 1 << 4; - const PARTIAL_ORD = 1 << 5; - const ORD = 1 << 6; - const PARTIAL_EQ = 1 << 7; - const EQ = 1 << 8; - } -} - -fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits { - let mut derivable_traits = DerivableTraits::empty(); - - if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() { - derivable_traits |= DerivableTraits::DEBUG; - } - - if item.can_derive_default(ctx) && !item.annotations().disallow_default() { - derivable_traits |= DerivableTraits::DEFAULT; - } - - 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; - } - } - - if item.can_derive_hash(ctx) { - derivable_traits |= DerivableTraits::HASH; - } - - if item.can_derive_partialord(ctx) { - derivable_traits |= DerivableTraits::PARTIAL_ORD; - } - - if item.can_derive_ord(ctx) { - derivable_traits |= DerivableTraits::ORD; - } - - if item.can_derive_partialeq(ctx) { - derivable_traits |= DerivableTraits::PARTIAL_EQ; - } - - if item.can_derive_eq(ctx) { - derivable_traits |= DerivableTraits::EQ; - } - - derivable_traits -} - -impl From for Vec<&'static str> { - fn from(derivable_traits: DerivableTraits) -> Vec<&'static str> { - [ - (DerivableTraits::DEBUG, "Debug"), - (DerivableTraits::DEFAULT, "Default"), - (DerivableTraits::COPY, "Copy"), - (DerivableTraits::CLONE, "Clone"), - (DerivableTraits::HASH, "Hash"), - (DerivableTraits::PARTIAL_ORD, "PartialOrd"), - (DerivableTraits::ORD, "Ord"), - (DerivableTraits::PARTIAL_EQ, "PartialEq"), - (DerivableTraits::EQ, "Eq"), - ] - .iter() - .filter_map(|&(flag, derive)| { - Some(derive).filter(|_| derivable_traits.contains(flag)) - }) - .collect() - } -} - -struct CodegenResult<'a> { - items: Vec, - dynamic_items: DynamicItems, - - /// A monotonic counter used to add stable unique id's to stuff that doesn't - /// need to be referenced by anything. - codegen_id: &'a Cell, - - /// Whether a bindgen union has been generated at least once. - saw_bindgen_union: bool, - - /// Whether an incomplete array has been generated at least once. - saw_incomplete_array: bool, - - /// Whether Objective C types have been seen at least once. - saw_objc: bool, - - /// Whether Apple block types have been seen at least once. - saw_block: bool, - - /// Whether a bitfield allocation unit has been seen at least once. - saw_bitfield_unit: bool, - - items_seen: HashSet, - /// The set of generated function/var names, needed because in C/C++ is - /// legal to do something like: - /// - /// ```c++ - /// extern "C" { - /// void foo(); - /// extern int bar; - /// } - /// - /// extern "C" { - /// void foo(); - /// extern int bar; - /// } - /// ``` - /// - /// Being these two different declarations. - functions_seen: HashSet, - vars_seen: HashSet, - - /// Used for making bindings to overloaded functions. Maps from a canonical - /// function name to the number of overloads we have already codegen'd for - /// that name. This lets us give each overload a unique suffix. - overload_counters: HashMap, -} - -impl<'a> CodegenResult<'a> { - fn new(codegen_id: &'a Cell) -> Self { - CodegenResult { - items: vec![], - dynamic_items: DynamicItems::new(), - saw_bindgen_union: false, - saw_incomplete_array: false, - saw_objc: false, - saw_block: false, - saw_bitfield_unit: false, - codegen_id, - items_seen: Default::default(), - functions_seen: Default::default(), - vars_seen: Default::default(), - overload_counters: Default::default(), - } - } - - fn dynamic_items(&mut self) -> &mut DynamicItems { - &mut self.dynamic_items - } - - fn saw_bindgen_union(&mut self) { - self.saw_bindgen_union = true; - } - - fn saw_incomplete_array(&mut self) { - self.saw_incomplete_array = true; - } - - fn saw_objc(&mut self) { - self.saw_objc = true; - } - - fn saw_block(&mut self) { - self.saw_block = true; - } - - fn saw_bitfield_unit(&mut self) { - self.saw_bitfield_unit = true; - } - - fn seen>(&self, item: Id) -> bool { - self.items_seen.contains(&item.into()) - } - - fn set_seen>(&mut self, item: Id) { - self.items_seen.insert(item.into()); - } - - fn seen_function(&self, name: &str) -> bool { - self.functions_seen.contains(name) - } - - fn saw_function(&mut self, name: &str) { - self.functions_seen.insert(name.into()); - } - - /// Get the overload number for the given function name. Increments the - /// counter internally so the next time we ask for the overload for this - /// name, we get the incremented value, and so on. - fn overload_number(&mut self, name: &str) -> u32 { - let counter = self.overload_counters.entry(name.into()).or_insert(0); - let number = *counter; - *counter += 1; - number - } - - fn seen_var(&self, name: &str) -> bool { - self.vars_seen.contains(name) - } - - fn saw_var(&mut self, name: &str) { - self.vars_seen.insert(name.into()); - } - - fn inner(&mut self, cb: F) -> Vec - where - F: FnOnce(&mut Self), - { - let mut new = Self::new(self.codegen_id); - - cb(&mut new); - - self.saw_incomplete_array |= new.saw_incomplete_array; - self.saw_objc |= new.saw_objc; - self.saw_block |= new.saw_block; - self.saw_bitfield_unit |= new.saw_bitfield_unit; - self.saw_bindgen_union |= new.saw_bindgen_union; - - new.items - } -} - -impl<'a> ops::Deref for CodegenResult<'a> { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl<'a> ops::DerefMut for CodegenResult<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -/// A trait to convert a rust type into a pointer, optionally const, to the same -/// type. -trait ToPtr { - fn to_ptr(self, is_const: bool) -> proc_macro2::TokenStream; -} - -impl ToPtr for proc_macro2::TokenStream { - fn to_ptr(self, is_const: bool) -> proc_macro2::TokenStream { - if is_const { - quote! { *const #self } - } else { - quote! { *mut #self } - } - } -} - -/// An extension trait for `proc_macro2::TokenStream` that lets us append any implicit -/// template parameters that exist for some type, if necessary. -trait AppendImplicitTemplateParams { - fn append_implicit_template_params( - &mut self, - ctx: &BindgenContext, - item: &Item, - ); -} - -impl AppendImplicitTemplateParams for proc_macro2::TokenStream { - fn append_implicit_template_params( - &mut self, - ctx: &BindgenContext, - item: &Item, - ) { - let item = item.id().into_resolver().through_type_refs().resolve(ctx); - - match *item.expect_type().kind() { - TypeKind::UnresolvedTypeRef(..) => { - unreachable!("already resolved unresolved type refs") - } - TypeKind::ResolvedTypeRef(..) => { - unreachable!("we resolved item through type refs") - } - - // None of these types ever have implicit template parameters. - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Pointer(..) | - TypeKind::Reference(..) | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Array(..) | - TypeKind::TypeParam | - TypeKind::Opaque | - TypeKind::Function(..) | - TypeKind::Enum(..) | - TypeKind::ObjCId | - TypeKind::ObjCSel | - TypeKind::TemplateInstantiation(..) => return, - _ => {} - } - - let params: Vec<_> = item - .used_template_params(ctx) - .iter() - .map(|p| { - p.try_to_rust_ty(ctx, &()) - .expect("template params cannot fail to be a rust type") - }) - .collect(); - if !params.is_empty() { - self.append_all(quote! { - < #( #params ),* > - }); - } - } -} - -trait CodeGenerator { - /// Extra information from the caller. - type Extra; - - /// Extra information returned to the caller. - type Return; - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - extra: &Self::Extra, - ) -> Self::Return; -} - -impl Item { - fn process_before_codegen( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult, - ) -> bool { - if !self.is_enabled_for_codegen(ctx) { - return false; - } - - if self.is_blocklisted(ctx) || result.seen(self.id()) { - debug!( - "::process_before_codegen: Ignoring hidden or seen: \ - self = {:?}", - self - ); - return false; - } - - if !ctx.codegen_items().contains(&self.id()) { - // 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); - } - - result.set_seen(self.id()); - true - } -} - -impl CodeGenerator for Item { - type Extra = (); - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - _extra: &(), - ) { - debug!("::codegen: self = {:?}", self); - if !self.process_before_codegen(ctx, result) { - return; - } - - match *self.kind() { - ItemKind::Module(ref module) => { - module.codegen(ctx, result, self); - } - ItemKind::Function(ref fun) => { - fun.codegen(ctx, result, self); - } - ItemKind::Var(ref var) => { - var.codegen(ctx, result, self); - } - ItemKind::Type(ref ty) => { - ty.codegen(ctx, result, self); - } - } - } -} - -impl CodeGenerator for Module { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - debug!("::codegen: item = {:?}", item); - - let codegen_self = |result: &mut CodegenResult, - found_any: &mut bool| { - for child in self.children() { - if ctx.codegen_items().contains(child) { - *found_any = true; - ctx.resolve_item(*child).codegen(ctx, result, &()); - } - } - - if item.id() == ctx.root_module() { - if result.saw_block { - utils::prepend_block_header(ctx, &mut *result); - } - if result.saw_bindgen_union { - utils::prepend_union_types(ctx, &mut *result); - } - if result.saw_incomplete_array { - utils::prepend_incomplete_array_types(ctx, &mut *result); - } - if ctx.need_bindgen_complex_type() { - utils::prepend_complex_type(&mut *result); - } - if result.saw_objc { - utils::prepend_objc_header(ctx, &mut *result); - } - if result.saw_bitfield_unit { - utils::prepend_bitfield_unit_type(ctx, &mut *result); - } - } - }; - - if !ctx.options().enable_cxx_namespaces || - (self.is_inline() && - !ctx.options().conservative_inline_namespaces) - { - codegen_self(result, &mut false); - return; - } - - let mut found_any = false; - let inner_items = result.inner(|result| { - result.push(root_import(ctx, item)); - - let path = item.namespace_aware_canonical_path(ctx).join("::"); - if let Some(raw_lines) = ctx.options().module_lines.get(&path) { - for raw_line in raw_lines { - found_any = true; - result.push( - proc_macro2::TokenStream::from_str(raw_line).unwrap(), - ); - } - } - - codegen_self(result, &mut found_any); - }); - - // Don't bother creating an empty module. - if !found_any { - return; - } - - let name = item.canonical_name(ctx); - let ident = ctx.rust_ident(name); - result.push(if item.id() == ctx.root_module() { - quote! { - #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] - pub mod #ident { - #( #inner_items )* - } - } - } else { - quote! { - pub mod #ident { - #( #inner_items )* - } - } - }); - } -} - -impl CodeGenerator for Var { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - use crate::ir::var::VarType; - debug!("::codegen: item = {:?}", item); - debug_assert!(item.is_enabled_for_codegen(ctx)); - - let canonical_name = item.canonical_name(ctx); - - if result.seen_var(&canonical_name) { - return; - } - result.saw_var(&canonical_name); - - let canonical_ident = ctx.rust_ident(&canonical_name); - - // We can't generate bindings to static variables of templates. The - // number of actual variables for a single declaration are open ended - // and we don't know what instantiations do or don't exist. - if !item.all_template_params(ctx).is_empty() { - return; - } - - let mut attrs = vec![]; - if let Some(comment) = item.comment(ctx) { - attrs.push(attributes::doc(comment)); - } - - let ty = self.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 ; - }); - } - VarType::Int(val) => { - let int_kind = self - .ty() - .into_resolver() - .through_type_aliases() - .through_type_refs() - .resolve(ctx) - .expect_type() - .as_integer() - .unwrap(); - let val = if int_kind.is_signed() { - helpers::ast_ty::int_expr(val) - } else { - helpers::ast_ty::uint_expr(val as _) - }; - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #val ; - }); - } - VarType::String(ref bytes) => { - // Account the trailing zero. - // - // TODO: Here we ignore the type we just made up, probably - // we should refactor how the variable type and ty id work. - let len = bytes.len() + 1; - let ty = quote! { - [u8; #len] - }; - - match String::from_utf8(bytes.clone()) { - Ok(string) => { - let cstr = helpers::ast_ty::cstr_expr(string); - if ctx - .options() - .rust_features - .static_lifetime_elision - { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : &#ty = #cstr ; - }); - } else { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : &'static #ty = #cstr ; - }); - } - } - Err(..) => { - let bytes = helpers::ast_ty::byte_array_expr(bytes); - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #bytes ; - }); - } - } - } - 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 ; - }); - } - } - } else { - // If necessary, apply a `#[link_name]` attribute - let link_name = self.mangled_name().unwrap_or_else(|| self.name()); - if !utils::names_will_be_identical_after_mangling( - &canonical_name, - link_name, - None, - ) { - attrs.push(attributes::link_name(link_name)); - } - - let maybe_mut = if self.is_const() { - quote! {} - } else { - quote! { mut } - }; - - let tokens = quote!( - extern "C" { - #(#attrs)* - pub static #maybe_mut #canonical_ident: #ty; - } - ); - - result.push(tokens); - } - } -} - -impl CodeGenerator for Type { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - debug!("::codegen: item = {:?}", item); - debug_assert!(item.is_enabled_for_codegen(ctx)); - - match *self.kind() { - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Array(..) | - TypeKind::Vector(..) | - TypeKind::Pointer(..) | - TypeKind::Reference(..) | - TypeKind::Function(..) | - TypeKind::ResolvedTypeRef(..) | - TypeKind::Opaque | - TypeKind::TypeParam => { - // These items don't need code generation, they only need to be - // converted to rust types in fields, arguments, and such. - // NOTE(emilio): If you add to this list, make sure to also add - // it to BindgenContext::compute_allowlisted_and_codegen_items. - } - TypeKind::TemplateInstantiation(ref inst) => { - inst.codegen(ctx, result, item) - } - TypeKind::BlockPointer(inner) => { - if !ctx.options().generate_block { - return; - } - - let inner_item = - inner.into_resolver().through_type_refs().resolve(ctx); - let name = item.canonical_name(ctx); - - let inner_rust_type = { - if let TypeKind::Function(fnsig) = - inner_item.kind().expect_type().kind() - { - utils::fnsig_block(ctx, fnsig) - } else { - 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) - } else { - quote! {} - }; - - tokens.append_all(quote! { - pub type #rust_name = #inner_rust_type ; - }); - - result.push(tokens); - result.saw_block(); - } - TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item), - TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => { - let inner_item = - inner.into_resolver().through_type_refs().resolve(ctx); - let name = item.canonical_name(ctx); - let path = item.canonical_path(ctx); - - { - let through_type_aliases = inner - .into_resolver() - .through_type_refs() - .through_type_aliases() - .resolve(ctx); - - // Try to catch the common pattern: - // - // typedef struct foo { ... } foo; - // - // here, and also other more complex cases like #946. - if through_type_aliases.canonical_path(ctx) == path { - return; - } - } - - // If this is a known named type, disallow generating anything - // for it too. - let spelling = self.name().expect("Unnamed alias?"); - if utils::type_from_named(ctx, spelling).is_some() { - return; - } - - let mut outer_params = item.used_template_params(ctx); - - let is_opaque = item.is_opaque(ctx, &()); - let inner_rust_type = if is_opaque { - outer_params = vec![]; - self.to_opaque(ctx, item) - } else { - // Its possible that we have better layout information than - // the inner type does, so fall back to an opaque blob based - // on our layout if converting the inner item fails. - let mut inner_ty = inner_item - .try_to_rust_ty_or_opaque(ctx, &()) - .unwrap_or_else(|_| self.to_opaque(ctx, item)); - inner_ty.append_implicit_template_params(ctx, inner_item); - inner_ty - }; - - { - // FIXME(emilio): This is a workaround to avoid generating - // incorrect type aliases because of types that we haven't - // been able to resolve (because, eg, they depend on a - // template parameter). - // - // It's kind of a shame not generating them even when they - // could be referenced, but we already do the same for items - // with invalid template parameters, and at least this way - // they can be replaced, instead of generating plain invalid - // code. - let inner_canon_type = - inner_item.expect_type().canonical_type(ctx); - if inner_canon_type.is_invalid_type_param() { - warn!( - "Item contained invalid named type, skipping: \ - {:?}, {:?}", - item, inner_item - ); - return; - } - } - - let rust_name = ctx.rust_ident(&name); - - let mut tokens = if let Some(comment) = item.comment(ctx) { - 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 - }; - - // We prefer using `pub use` over `pub type` because of: - // https://github.com/rust-lang/rust/issues/26264 - // These are the only characters allowed in simple - // paths, eg `good::dogs::Bront`. - if inner_rust_type.to_string().chars().all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ')) && outer_params.is_empty() && - !is_opaque && - alias_style == AliasVariation::TypeAlias && - inner_item.expect_type().canonical_type(ctx).is_enum() - { - tokens.append_all(quote! { - pub use - }); - let path = top_level_path(ctx, item); - tokens.append_separated(path, quote!(::)); - tokens.append_all(quote! { - :: #inner_rust_type as #rust_name ; - }); - result.push(tokens); - return; - } - - tokens.append_all(match alias_style { - AliasVariation::TypeAlias => quote! { - 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 derivable_traits = derives_of_item(item, ctx); - if !derivable_traits.is_empty() { - let derives: Vec<_> = derivable_traits.into(); - attributes.push(attributes::derives(&derives)) - } - - quote! { - #( #attributes )* - pub struct #rust_name - } - } - }); - - let params: Vec<_> = outer_params - .into_iter() - .filter_map(|p| p.as_template_param(ctx, &())) - .collect(); - if params - .iter() - .any(|p| ctx.resolve_type(*p).is_invalid_type_param()) - { - warn!( - "Item contained invalid template \ - parameter: {:?}", - item - ); - return; - } - let params: Vec<_> = params - .iter() - .map(|p| { - p.try_to_rust_ty(ctx, &()).expect( - "type parameters can always convert to rust ty OK", - ) - }) - .collect(); - - if !params.is_empty() { - tokens.append_all(quote! { - < #( #params ),* > - }); - } - - tokens.append_all(match alias_style { - AliasVariation::TypeAlias => quote! { - = #inner_rust_type ; - }, - AliasVariation::NewType | AliasVariation::NewTypeDeref => { - quote! { - (pub #inner_rust_type) ; - } - } - }); - - if alias_style == AliasVariation::NewTypeDeref { - let prefix = ctx.trait_prefix(); - tokens.append_all(quote! { - impl ::#prefix::ops::Deref for #rust_name { - type Target = #inner_rust_type; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl ::#prefix::ops::DerefMut for #rust_name { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - }); - } - - result.push(tokens); - } - TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item), - TypeKind::ObjCId | TypeKind::ObjCSel => { - result.saw_objc(); - } - TypeKind::ObjCInterface(ref interface) => { - interface.codegen(ctx, result, item) - } - ref u @ TypeKind::UnresolvedTypeRef(..) => { - unreachable!("Should have been resolved after parsing {:?}!", u) - } - } - } -} - -struct Vtable<'a> { - item_id: ItemId, - /// A reference to the originating compound object. - #[allow(dead_code)] - comp_info: &'a CompInfo, -} - -impl<'a> Vtable<'a> { - fn new(item_id: ItemId, comp_info: &'a CompInfo) -> Self { - Vtable { item_id, comp_info } - } -} - -impl<'a> CodeGenerator for Vtable<'a> { - type Extra = Item; - type Return = (); - - fn codegen<'b>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'b>, - item: &Item, - ) { - assert_eq!(item.id(), self.item_id); - debug_assert!(item.is_enabled_for_codegen(ctx)); - let name = ctx.rust_ident(&self.canonical_name(ctx)); - - // For now, we will only generate vtables for classes that: - // - do not inherit from others (compilers merge VTable from primary parent class). - // - do not contain a virtual destructor (requires ordering; platforms generate different vtables). - if ctx.options().vtable_generation && - self.comp_info.base_members().is_empty() && - self.comp_info.destructor().is_none() - { - let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx)); - - let methods = self - .comp_info - .methods() - .iter() - .filter_map(|m| { - if !m.is_virtual() { - return None; - } - - 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"), - }; - - // FIXME: Is there a canonical name without the class prepended? - let function_name = function_item.canonical_name(ctx); - - // FIXME: Need to account for overloading with times_seen (separately from regular function path). - let function_name = ctx.rust_ident(function_name); - let mut args = utils::fnsig_arguments(ctx, signature); - let ret = utils::fnsig_return_ty(ctx, signature); - - args[0] = if m.is_const() { - quote! { this: *const #class_ident } - } else { - quote! { this: *mut #class_ident } - }; - - Some(quote! { - pub #function_name : unsafe extern "C" fn( #( #args ),* ) #ret - }) - }) - .collect::>(); - - result.push(quote! { - #[repr(C)] - 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); - - result.push(quote! { - #[repr(C)] - pub struct #name ( #void ); - }); - } - } -} - -impl<'a> ItemCanonicalName for Vtable<'a> { - fn canonical_name(&self, ctx: &BindgenContext) -> String { - format!("{}__bindgen_vtable", self.item_id.canonical_name(ctx)) - } -} - -impl<'a> TryToRustTy for Vtable<'a> { - type Extra = (); - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - let name = ctx.rust_ident(self.canonical_name(ctx)); - Ok(quote! { - #name - }) - } -} - -impl CodeGenerator for TemplateInstantiation { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - debug_assert!(item.is_enabled_for_codegen(ctx)); - - // Although uses of instantiations don't need code generation, and are - // just converted to rust types in fields, vars, etc, we take this - // opportunity to generate tests for their layout here. If the - // instantiation is opaque, then its presumably because we don't - // properly understand it (maybe because of specializations), and so we - // shouldn't emit layout tests either. - if !ctx.options().layout_tests || self.is_opaque(ctx, item) { - return; - } - - // If there are any unbound type parameters, then we can't generate a - // layout test because we aren't dealing with a concrete type with a - // concrete size and alignment. - if ctx.uses_any_template_parameters(item.id()) { - return; - } - - let layout = item.kind().expect_type().layout(ctx); - - if let Some(layout) = layout { - let size = layout.size; - let align = layout.align; - - let name = item.full_disambiguated_name(ctx); - let mut fn_name = - format!("__bindgen_test_layout_{}_instantiation", name); - let times_seen = result.overload_number(&fn_name); - if times_seen > 0 { - write!(&mut fn_name, "_{}", times_seen).unwrap(); - } - - let fn_name = ctx.rust_ident_raw(fn_name); - - let prefix = ctx.trait_prefix(); - let ident = item.to_rust_ty_or_opaque(ctx, &()); - let size_of_expr = quote! { - ::#prefix::mem::size_of::<#ident>() - }; - let align_of_expr = quote! { - ::#prefix::mem::align_of::<#ident>() - }; - - let item = quote! { - #[test] - fn #fn_name() { - assert_eq!(#size_of_expr, #size, - concat!("Size of template specialization: ", - stringify!(#ident))); - assert_eq!(#align_of_expr, #align, - concat!("Alignment of template specialization: ", - stringify!(#ident))); - } - }; - - result.push(item); - } - } -} - -/// Trait for implementing the code generation of a struct or union field. -trait FieldCodegen<'a> { - type Extra; - - fn codegen( - &self, - ctx: &BindgenContext, - fields_should_be_private: bool, - codegen_depth: usize, - accessor_kind: FieldAccessorKind, - parent: &CompInfo, - result: &mut CodegenResult, - struct_layout: &mut StructLayoutTracker, - fields: &mut F, - methods: &mut M, - extra: Self::Extra, - ) where - F: Extend, - M: Extend; -} - -impl<'a> FieldCodegen<'a> for Field { - type Extra = (); - - fn codegen( - &self, - ctx: &BindgenContext, - fields_should_be_private: bool, - codegen_depth: usize, - accessor_kind: FieldAccessorKind, - parent: &CompInfo, - result: &mut CodegenResult, - struct_layout: &mut StructLayoutTracker, - fields: &mut F, - methods: &mut M, - _: (), - ) where - F: Extend, - M: Extend, - { - match *self { - Field::DataMember(ref data) => { - data.codegen( - ctx, - fields_should_be_private, - codegen_depth, - accessor_kind, - parent, - result, - struct_layout, - fields, - methods, - (), - ); - } - Field::Bitfields(ref unit) => { - unit.codegen( - ctx, - fields_should_be_private, - codegen_depth, - accessor_kind, - parent, - result, - struct_layout, - fields, - methods, - (), - ); - } - } - } -} - -impl<'a> FieldCodegen<'a> for FieldData { - type Extra = (); - - fn codegen( - &self, - ctx: &BindgenContext, - fields_should_be_private: bool, - codegen_depth: usize, - accessor_kind: FieldAccessorKind, - parent: &CompInfo, - result: &mut CodegenResult, - struct_layout: &mut StructLayoutTracker, - fields: &mut F, - methods: &mut M, - _: (), - ) where - F: Extend, - M: Extend, - { - // Bitfields are handled by `FieldCodegen` implementations for - // `BitfieldUnit` and `Bitfield`. - assert!(self.bitfield_width().is_none()); - - let field_item = - self.ty().into_resolver().through_type_refs().resolve(ctx); - let field_ty = field_item.expect_type(); - let mut ty = self.ty().to_rust_ty_or_opaque(ctx, &()); - ty.append_implicit_template_params(ctx, field_item); - - // NB: If supported, we use proper `union` types. - let ty = if parent.is_union() && !struct_layout.is_rust_union() { - result.saw_bindgen_union(); - if ctx.options().enable_cxx_namespaces { - quote! { - root::__BindgenUnionField<#ty> - } - } else { - quote! { - __BindgenUnionField<#ty> - } - } - } else if let Some(item) = field_ty.is_incomplete_array(ctx) { - result.saw_incomplete_array(); - - let inner = item.to_rust_ty_or_opaque(ctx, &()); - - if ctx.options().enable_cxx_namespaces { - quote! { - root::__IncompleteArrayField<#inner> - } - } else { - quote! { - __IncompleteArrayField<#inner> - } - } - } else { - ty - }; - - let mut field = quote! {}; - if ctx.options().generate_comments { - if let Some(raw_comment) = self.comment() { - let comment = - comment::preprocess(raw_comment, codegen_depth + 1); - field = attributes::doc(comment); - } - } - - let field_name = self - .name() - .map(|name| ctx.rust_mangle(name).into_owned()) - .expect("Each field should have a name in codegen!"); - let field_ident = ctx.rust_ident_raw(field_name.as_str()); - - if let Some(padding_field) = - struct_layout.saw_field(&field_name, field_ty, self.offset()) - { - fields.extend(Some(padding_field)); - } - - let is_private = (!self.is_public() && - ctx.options().respect_cxx_access_specs) || - self.annotations() - .private_fields() - .unwrap_or(fields_should_be_private); - - let accessor_kind = - self.annotations().accessor_kind().unwrap_or(accessor_kind); - - if is_private { - field.append_all(quote! { - #field_ident : #ty , - }); - } else { - field.append_all(quote! { - pub #field_ident : #ty , - }); - } - - fields.extend(Some(field)); - - // TODO: Factor the following code out, please! - if accessor_kind == FieldAccessorKind::None { - return; - } - - let getter_name = ctx.rust_ident_raw(format!("get_{}", field_name)); - let mutable_getter_name = - ctx.rust_ident_raw(format!("get_{}_mut", field_name)); - let field_name = ctx.rust_ident_raw(field_name); - - methods.extend(Some(match accessor_kind { - FieldAccessorKind::None => unreachable!(), - FieldAccessorKind::Regular => { - quote! { - #[inline] - pub fn #getter_name(&self) -> & #ty { - &self.#field_name - } - - #[inline] - pub fn #mutable_getter_name(&mut self) -> &mut #ty { - &mut self.#field_name - } - } - } - FieldAccessorKind::Unsafe => { - quote! { - #[inline] - pub unsafe fn #getter_name(&self) -> & #ty { - &self.#field_name - } - - #[inline] - pub unsafe fn #mutable_getter_name(&mut self) -> &mut #ty { - &mut self.#field_name - } - } - } - FieldAccessorKind::Immutable => { - quote! { - #[inline] - pub fn #getter_name(&self) -> & #ty { - &self.#field_name - } - } - } - })); - } -} - -impl BitfieldUnit { - /// Get the constructor name for this bitfield unit. - fn ctor_name(&self) -> proc_macro2::TokenStream { - let ctor_name = Ident::new( - &format!("new_bitfield_{}", self.nth()), - Span::call_site(), - ); - quote! { - #ctor_name - } - } -} - -impl Bitfield { - /// Extend an under construction bitfield unit constructor with this - /// bitfield. This sets the relevant bits on the `__bindgen_bitfield_unit` - /// variable that's being constructed. - fn extend_ctor_impl( - &self, - ctx: &BindgenContext, - 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 \ - representable as an int", - ); - - let offset = self.offset_into_unit(); - let width = self.width() as u8; - let prefix = ctx.trait_prefix(); - - ctor_impl.append_all(quote! { - __bindgen_bitfield_unit.set( - #offset, - #width, - { - let #param_name: #bitfield_int_ty = unsafe { - ::#prefix::mem::transmute(#param_name) - }; - #param_name as u64 - } - ); - }); - - ctor_impl - } -} - -fn access_specifier( - ctx: &BindgenContext, - is_pub: bool, -) -> proc_macro2::TokenStream { - if is_pub || !ctx.options().respect_cxx_access_specs { - quote! { pub } - } else { - quote! {} - } -} - -impl<'a> FieldCodegen<'a> for BitfieldUnit { - type Extra = (); - - fn codegen( - &self, - ctx: &BindgenContext, - fields_should_be_private: bool, - codegen_depth: usize, - accessor_kind: FieldAccessorKind, - parent: &CompInfo, - result: &mut CodegenResult, - struct_layout: &mut StructLayoutTracker, - fields: &mut F, - methods: &mut M, - _: (), - ) where - F: Extend, - M: Extend, - { - use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; - - result.saw_bitfield_unit(); - - let layout = self.layout(); - let unit_field_ty = helpers::bitfield_unit(ctx, layout); - let field_ty = { - if parent.is_union() && !struct_layout.is_rust_union() { - result.saw_bindgen_union(); - if ctx.options().enable_cxx_namespaces { - quote! { - root::__BindgenUnionField<#unit_field_ty> - } - } else { - quote! { - __BindgenUnionField<#unit_field_ty> - } - } - } else { - unit_field_ty.clone() - } - }; - - { - 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 align_field = quote! { - pub #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); - - let ctor_name = self.ctor_name(); - let mut ctor_params = vec![]; - let mut ctor_impl = quote! {}; - - // We cannot generate any constructor if the underlying storage can't - // implement AsRef<[u8]> / AsMut<[u8]> / etc, or can't derive Default. - // - // We don't check `larger_arrays` here because Default does still have - // the 32 items limitation. - let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT; - - let mut access_spec = !fields_should_be_private; - for bf in self.bitfields() { - // Codegen not allowed for anonymous bitfields - if bf.name().is_none() { - continue; - } - - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && - !ctx.options().rust_features().larger_arrays - { - continue; - } - - access_spec &= bf.is_public(); - let mut bitfield_representable_as_int = true; - - bf.codegen( - ctx, - fields_should_be_private, - codegen_depth, - accessor_kind, - parent, - result, - struct_layout, - fields, - methods, - (&unit_field_name, &mut bitfield_representable_as_int), - ); - - // Generating a constructor requires the bitfield to be representable as an integer. - if !bitfield_representable_as_int { - generate_ctor = false; - continue; - } - - let param_name = bitfield_getter_name(ctx, bf); - let bitfield_ty_item = ctx.resolve_item(bf.ty()); - let bitfield_ty = bitfield_ty_item.expect_type(); - let bitfield_ty = - bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); - - ctor_params.push(quote! { - #param_name : #bitfield_ty - }); - ctor_impl = bf.extend_ctor_impl(ctx, param_name, ctor_impl); - } - - let access_spec = access_specifier(ctx, access_spec); - - let field = quote! { - #access_spec #unit_field_ident : #field_ty , - }; - fields.extend(Some(field)); - - if generate_ctor { - methods.extend(Some(quote! { - #[inline] - #access_spec fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty { - let mut __bindgen_bitfield_unit: #unit_field_ty = Default::default(); - #ctor_impl - __bindgen_bitfield_unit - } - })); - } - - struct_layout.saw_bitfield_unit(layout); - } -} - -fn bitfield_getter_name( - ctx: &BindgenContext, - bitfield: &Bitfield, -) -> proc_macro2::TokenStream { - let name = bitfield.getter_name(); - let name = ctx.rust_ident_raw(name); - quote! { #name } -} - -fn bitfield_setter_name( - ctx: &BindgenContext, - bitfield: &Bitfield, -) -> proc_macro2::TokenStream { - let setter = bitfield.setter_name(); - let setter = ctx.rust_ident_raw(setter); - quote! { #setter } -} - -impl<'a> FieldCodegen<'a> for Bitfield { - type Extra = (&'a str, &'a mut bool); - - fn codegen( - &self, - ctx: &BindgenContext, - fields_should_be_private: bool, - _codegen_depth: usize, - _accessor_kind: FieldAccessorKind, - parent: &CompInfo, - _result: &mut CodegenResult, - struct_layout: &mut StructLayoutTracker, - _fields: &mut F, - methods: &mut M, - (unit_field_name, bitfield_representable_as_int): (&'a str, &mut bool), - ) where - F: Extend, - M: Extend, - { - let prefix = ctx.trait_prefix(); - let getter_name = bitfield_getter_name(ctx, self); - let setter_name = bitfield_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_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; - } - }; - - let bitfield_ty = - bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); - - let offset = self.offset_into_unit(); - let width = self.width() as u8; - let access_spec = access_specifier( - ctx, - self.is_public() && !fields_should_be_private, - ); - - if parent.is_union() && !struct_layout.is_rust_union() { - methods.extend(Some(quote! { - #[inline] - #access_spec fn #getter_name(&self) -> #bitfield_ty { - unsafe { - ::#prefix::mem::transmute( - self.#unit_field_ident.as_ref().get(#offset, #width) - as #bitfield_int_ty - ) - } - } - - #[inline] - #access_spec fn #setter_name(&mut self, val: #bitfield_ty) { - unsafe { - let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); - self.#unit_field_ident.as_mut().set( - #offset, - #width, - val as u64 - ) - } - } - })); - } else { - methods.extend(Some(quote! { - #[inline] - #access_spec fn #getter_name(&self) -> #bitfield_ty { - unsafe { - ::#prefix::mem::transmute( - self.#unit_field_ident.get(#offset, #width) - as #bitfield_int_ty - ) - } - } - - #[inline] - #access_spec fn #setter_name(&mut self, val: #bitfield_ty) { - unsafe { - let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); - self.#unit_field_ident.set( - #offset, - #width, - val as u64 - ) - } - } - })); - } - } -} - -impl CodeGenerator for CompInfo { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - 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 - // also don't output template specializations, neither total or partial. - if self.has_non_type_template_params() { - return; - } - - let ty = item.expect_type(); - let layout = ty.layout(ctx); - let mut packed = self.is_packed(ctx, layout.as_ref()); - - let canonical_name = item.canonical_name(ctx); - let canonical_ident = ctx.rust_ident(&canonical_name); - - // Generate the vtable from the method list if appropriate. - // - // TODO: I don't know how this could play with virtual methods that are - // not in the list of methods found by us, we'll see. Also, could the - // order of the vtable pointers vary? - // - // FIXME: Once we generate proper vtables, we need to codegen the - // vtable, but *not* generate a field for it in the case that - // HasVtable::has_vtable_ptr is false but HasVtable::has_vtable is true. - // - // Also, we need to generate the vtable in such a way it "inherits" from - // the parent too. - let is_opaque = item.is_opaque(ctx, &()); - let mut fields = vec![]; - let mut struct_layout = - StructLayoutTracker::new(ctx, self, ty, &canonical_name); - - if !is_opaque { - if item.has_vtable_ptr(ctx) { - let vtable = Vtable::new(item.id(), self); - vtable.codegen(ctx, result, item); - - let vtable_type = vtable - .try_to_rust_ty(ctx, &()) - .expect("vtable to Rust type conversion is infallible") - .to_ptr(true); - - fields.push(quote! { - pub vtable_: #vtable_type , - }); - - struct_layout.saw_vtable(); - } - - for base in self.base_members() { - if !base.requires_storage(ctx) { - continue; - } - - let inner_item = ctx.resolve_item(base.ty); - let mut inner = inner_item.to_rust_ty_or_opaque(ctx, &()); - inner.append_implicit_template_params(ctx, inner_item); - let field_name = ctx.rust_ident(&base.field_name); - - struct_layout.saw_base(inner_item.expect_type()); - - let access_spec = access_specifier(ctx, base.is_public()); - fields.push(quote! { - #access_spec #field_name: #inner, - }); - } - } - - let mut methods = vec![]; - if !is_opaque { - let codegen_depth = item.codegen_depth(ctx); - let fields_should_be_private = - item.annotations().private_fields().unwrap_or(false); - let struct_accessor_kind = item - .annotations() - .accessor_kind() - .unwrap_or(FieldAccessorKind::None); - for field in self.fields() { - field.codegen( - ctx, - fields_should_be_private, - codegen_depth, - struct_accessor_kind, - self, - result, - &mut struct_layout, - &mut fields, - &mut methods, - (), - ); - } - // Check whether an explicit padding field is needed - // at the end. - if let Some(comp_layout) = layout { - fields.extend( - struct_layout - .add_tail_padding(&canonical_name, comp_layout), - ); - } - } - - if is_opaque { - // Opaque item should not have generated methods, fields. - debug_assert!(fields.is_empty()); - debug_assert!(methods.is_empty()); - } - - let is_union = self.kind() == CompKind::Union; - let layout = item.kind().expect_type().layout(ctx); - let zero_sized = item.is_zero_sized(ctx); - let forward_decl = self.is_forward_declaration(); - - let mut explicit_align = None; - - // C++ requires every struct to be addressable, so what C++ compilers do - // is making the struct 1-byte sized. - // - // This is apparently not the case for C, see: - // https://github.com/rust-lang/rust-bindgen/issues/551 - // - // Just get the layout, and assume C++ if not. - // - // NOTE: This check is conveniently here to avoid the dummy fields we - // may add for unused template parameters. - if !forward_decl && zero_sized { - let has_address = if is_opaque { - // Generate the address field if it's an opaque type and - // couldn't determine the layout of the blob. - layout.is_none() - } else { - layout.map_or(true, |l| l.size != 0) - }; - - 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, - }); - } - } - - if is_opaque { - match layout { - Some(l) => { - explicit_align = Some(l.align); - - let ty = helpers::blob(ctx, l); - fields.push(quote! { - pub _bindgen_opaque_blob: #ty , - }); - } - None => { - warn!("Opaque type without layout! Expect dragons!"); - } - } - } else if !is_union && !zero_sized { - if let Some(padding_field) = - layout.and_then(|layout| struct_layout.pad_struct(layout)) - { - fields.push(padding_field); - } - - if let Some(layout) = layout { - if struct_layout.requires_explicit_align(layout) { - if layout.align == 1 { - 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 forward_decl { - fields.push(quote! { - _unused: [u8; 0], - }); - } - - let mut generic_param_names = vec![]; - - for (idx, ty) in item.used_template_params(ctx).iter().enumerate() { - let param = ctx.resolve_type(*ty); - let name = param.name().unwrap(); - let ident = ctx.rust_ident(name); - generic_param_names.push(ident.clone()); - - let prefix = ctx.trait_prefix(); - let field_name = ctx.rust_ident(format!("_phantom_{}", idx)); - fields.push(quote! { - pub #field_name : ::#prefix::marker::PhantomData< - ::#prefix::cell::UnsafeCell<#ident> - > , - }); - } - - let generics = if !generic_param_names.is_empty() { - let generic_param_names = generic_param_names.clone(); - quote! { - < #( #generic_param_names ),* > - } - } else { - quote! {} - }; - - let mut attributes = vec![]; - let mut needs_clone_impl = false; - let mut needs_default_impl = false; - let mut needs_debug_impl = false; - let mut needs_partialeq_impl = false; - if let Some(comment) = item.comment(ctx) { - attributes.push(attributes::doc(comment)); - } - if packed && !is_opaque { - 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) - }; - 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. - let explicit = helpers::ast_ty::int_expr(explicit as i64); - attributes.push(quote! { - #[repr(align(#explicit))] - }); - } - } - - let derivable_traits = derives_of_item(item, ctx); - if !derivable_traits.contains(DerivableTraits::DEBUG) { - needs_debug_impl = ctx.options().derive_debug && - ctx.options().impl_debug && - !ctx.no_debug_by_name(item) && - !item.annotations().disallow_debug(); - } - - if !derivable_traits.contains(DerivableTraits::DEFAULT) { - needs_default_impl = ctx.options().derive_default && - !self.is_forward_declaration() && - !ctx.no_default_by_name(item) && - !item.annotations().disallow_default(); - } - - let all_template_params = item.all_template_params(ctx); - - if derivable_traits.contains(DerivableTraits::COPY) && - !derivable_traits.contains(DerivableTraits::CLONE) - { - needs_clone_impl = true; - } - - if !derivable_traits.contains(DerivableTraits::PARTIAL_EQ) { - needs_partialeq_impl = ctx.options().derive_partialeq && - ctx.options().impl_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == - CanDerive::Manually; - } - - let mut derives: Vec<_> = derivable_traits.into(); - derives.extend(item.annotations().derives().iter().map(String::as_str)); - - // The custom derives callback may return a list of derive attributes; - // add them to the end of the list. - let custom_derives; - if let Some(cb) = &ctx.options().parse_callbacks { - custom_derives = cb.add_derives(&canonical_name); - // 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())); - }; - - if !derives.is_empty() { - attributes.push(attributes::derives(&derives)) - } - - if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) - { - attributes.push(attributes::must_use()); - } - - let mut tokens = if is_union && struct_layout.is_rust_union() { - quote! { - #( #attributes )* - pub union #canonical_ident - } - } else { - quote! { - #( #attributes )* - pub struct #canonical_ident - } - }; - - tokens.append_all(quote! { - #generics { - #( #fields )* - } - }); - result.push(tokens); - - // Generate the inner types and all that stuff. - // - // TODO: In the future we might want to be smart, and use nested - // modules, and whatnot. - for ty in self.inner_types() { - let child_item = ctx.resolve_item(*ty); - // assert_eq!(child_item.parent_id(), item.id()); - child_item.codegen(ctx, result, &()); - } - - // NOTE: Some unexposed attributes (like alignment attributes) may - // 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 - ); - } - - if all_template_params.is_empty() { - if !is_opaque { - for var in self.inner_vars() { - ctx.resolve_item(*var).codegen(ctx, result, &()); - } - } - - if ctx.options().layout_tests && !self.is_forward_declaration() { - if let Some(layout) = layout { - let fn_name = - format!("bindgen_test_layout_{}", canonical_ident); - let fn_name = ctx.rust_ident_raw(fn_name); - let prefix = ctx.trait_prefix(); - let size_of_expr = quote! { - ::#prefix::mem::size_of::<#canonical_ident>() - }; - let align_of_expr = quote! { - ::#prefix::mem::align_of::<#canonical_ident>() - }; - let size = layout.size; - let align = layout.align; - - let check_struct_align = if align > - ctx.target_pointer_size() && - !ctx.options().rust_features().repr_align - { - None - } else { - Some(quote! { - assert_eq!(#align_of_expr, - #align, - concat!("Alignment of ", stringify!(#canonical_ident))); - - }) - }; - - // FIXME when [issue #465](https://github.com/rust-lang/rust-bindgen/issues/465) ready - let too_many_base_vtables = self - .base_members() - .iter() - .filter(|base| base.ty.has_vtable(ctx)) - .count() > - 1; - - let should_skip_field_offset_checks = - is_opaque || too_many_base_vtables; - - let check_field_offset = if should_skip_field_offset_checks - { - vec![] - } else { - let asserts = 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(); - field.offset().map(|offset| { - let field_offset = offset / 8; - let field_name = ctx.rust_ident(name); - - quote! { - assert_eq!( - unsafe { - &(*(::#prefix::ptr::null::<#canonical_ident>())).#field_name as *const _ as usize - }, - #field_offset, - concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name)) - ); - } - }) - }) - .collect::>(); - - asserts - }; - - let item = quote! { - #[test] - fn #fn_name() { - assert_eq!(#size_of_expr, - #size, - concat!("Size of: ", stringify!(#canonical_ident))); - - #check_struct_align - #( #check_field_offset )* - } - }; - result.push(item); - } - } - - let mut method_names = Default::default(); - if ctx.options().codegen_config.methods() { - for method in self.methods() { - assert!(method.kind() != MethodKind::Constructor); - method.codegen_method( - ctx, - &mut methods, - &mut method_names, - result, - self, - ); - } - } - - if ctx.options().codegen_config.constructors() { - for sig in self.constructors() { - Method::new( - MethodKind::Constructor, - *sig, - /* const */ - false, - ) - .codegen_method( - ctx, - &mut methods, - &mut method_names, - result, - self, - ); - } - } - - if ctx.options().codegen_config.destructors() { - if let Some((kind, destructor)) = self.destructor() { - debug_assert!(kind.is_destructor()); - Method::new(kind, destructor, false).codegen_method( - ctx, - &mut methods, - &mut method_names, - result, - self, - ); - } - } - } - - // NB: We can't use to_rust_ty here since for opaque types this tries to - // use the specialization knowledge to generate a blob field. - let ty_for_impl = quote! { - #canonical_ident #generics - }; - - if needs_clone_impl { - result.push(quote! { - impl #generics Clone for #ty_for_impl { - fn clone(&self) -> Self { *self } - } - }); - } - - 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 - } - } - }; - // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does - // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to - // non-zero padding bytes, especially when forwards/backwards compatability is - // involved. - result.push(quote! { - impl #generics Default for #ty_for_impl { - fn default() -> Self { - #body - } - } - }); - } - - if needs_debug_impl { - let impl_ = impl_debug::gen_debug_impl( - ctx, - self.fields(), - item, - self.kind(), - ); - - let prefix = ctx.trait_prefix(); - - result.push(quote! { - impl #generics ::#prefix::fmt::Debug for #ty_for_impl { - #impl_ - } - }); - } - - if needs_partialeq_impl { - if let Some(impl_) = impl_partialeq::gen_partialeq_impl( - ctx, - self, - item, - &ty_for_impl, - ) { - let partialeq_bounds = if !generic_param_names.is_empty() { - let bounds = generic_param_names.iter().map(|t| { - quote! { #t: PartialEq } - }); - quote! { where #( #bounds ),* } - } else { - quote! {} - }; - - let prefix = ctx.trait_prefix(); - result.push(quote! { - impl #generics ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds { - #impl_ - } - }); - } - } - - if !methods.is_empty() { - result.push(quote! { - impl #generics #ty_for_impl { - #( #methods )* - } - }); - } - } -} - -trait MethodCodegen { - fn codegen_method<'a>( - &self, - ctx: &BindgenContext, - methods: &mut Vec, - method_names: &mut HashMap, - result: &mut CodegenResult<'a>, - parent: &CompInfo, - ); -} - -impl MethodCodegen for Method { - fn codegen_method<'a>( - &self, - ctx: &BindgenContext, - methods: &mut Vec, - method_names: &mut HashMap, - result: &mut CodegenResult<'a>, - _parent: &CompInfo, - ) { - assert!({ - let cc = &ctx.options().codegen_config; - match self.kind() { - MethodKind::Constructor => cc.constructors(), - MethodKind::Destructor => cc.destructors(), - MethodKind::VirtualDestructor { .. } => cc.destructors(), - MethodKind::Static | - MethodKind::Normal | - MethodKind::Virtual { .. } => cc.methods(), - } - }); - - // TODO(emilio): We could generate final stuff at least. - if self.is_virtual() { - return; // FIXME - } - - // First of all, output the actual function. - let function_item = ctx.resolve_item(self.signature()); - if !function_item.process_before_codegen(ctx, result) { - return; - } - 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 signature_item = ctx.resolve_item(function.signature()); - let mut name = match self.kind() { - MethodKind::Constructor => "new".into(), - MethodKind::Destructor => "destruct".into(), - _ => function.name().to_owned(), - }; - - let signature = match *signature_item.expect_type().kind() { - TypeKind::Function(ref sig) => sig, - _ => panic!("How in the world?"), - }; - - if let (Abi::ThisCall, false) = - (signature.abi(), ctx.options().rust_features().thiscall_abi) - { - return; - } - - // Do not generate variadic methods, since rust does not allow - // implementing them, and we don't do a good job at it anyway. - if signature.is_variadic() { - return; - } - - let count = { - let count = method_names.entry(name.clone()).or_insert(0); - *count += 1; - *count - 1 - }; - - if count != 0 { - name.push_str(&count.to_string()); - } - - let mut function_name = function_item.canonical_name(ctx); - if times_seen > 0 { - write!(&mut function_name, "{}", times_seen).unwrap(); - } - let function_name = ctx.rust_ident(function_name); - let mut args = utils::fnsig_arguments(ctx, signature); - let mut ret = utils::fnsig_return_ty(ctx, signature); - - if !self.is_static() && !self.is_constructor() { - args[0] = if self.is_const() { - quote! { &self } - } else { - quote! { &mut self } - }; - } - - // If it's a constructor, we always return `Self`, and we inject the - // "this" parameter, so there's no need to ask the user for it. - // - // Note that constructors in Clang are represented as functions with - // return-type = void. - if self.is_constructor() { - args.remove(0); - ret = quote! { -> Self }; - } - - let mut exprs = - helpers::ast_ty::arguments_from_signature(signature, ctx); - - let mut stmts = vec![]; - - // If it's a constructor, we need to insert an extra parameter with a - // 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() - } - }; - stmts.push(tmp_variable_decl); - } else if !self.is_static() { - assert!(!exprs.is_empty()); - exprs[0] = quote! { - self - }; - }; - - let call = quote! { - #function_name (#( #exprs ),* ) - }; - - stmts.push(call); - - if self.is_constructor() { - stmts.push(if ctx.options().rust_features().maybe_uninit { - quote! { - __bindgen_tmp.assume_init() - } - } else { - quote! { - __bindgen_tmp - } - }) - } - - let block = quote! { - #( #stmts );* - }; - - let mut attrs = vec![attributes::inline()]; - - if signature.must_use() && - ctx.options().rust_features().must_use_function - { - attrs.push(attributes::must_use()); - } - - let name = ctx.rust_ident(&name); - methods.push(quote! { - #(#attrs)* - pub unsafe fn #name ( #( #args ),* ) #ret { - #block - } - }); - } -} - -/// A helper type that represents different enum variations. -#[derive(Copy, Clone, PartialEq, Debug)] -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. - Rust { - /// Indicates whether the generated struct should be `#[non_exhaustive]` - non_exhaustive: bool, - }, - /// The code for this enum will use a newtype - NewType { - /// Indicates whether the newtype will have bitwise operators - is_bitfield: bool, - }, - /// The code for this enum will use consts - Consts, - /// The code for this enum will use a module containing consts - ModuleConsts, -} - -impl EnumVariation { - 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) - } -} - -impl Default for EnumVariation { - fn default() -> EnumVariation { - EnumVariation::Consts - } -} - -impl std::str::FromStr for EnumVariation { - type Err = std::io::Error; - - /// Create a `EnumVariation` from a string. - fn from_str(s: &str) -> Result { - match s { - "rust" => Ok(EnumVariation::Rust { - non_exhaustive: false, - }), - "rust_non_exhaustive" => Ok(EnumVariation::Rust { - non_exhaustive: true, - }), - "bitfield" => Ok(EnumVariation::NewType { is_bitfield: true }), - "consts" => Ok(EnumVariation::Consts), - "moduleconsts" => Ok(EnumVariation::ModuleConsts), - "newtype" => Ok(EnumVariation::NewType { is_bitfield: false }), - _ => Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - concat!( - "Got an invalid EnumVariation. Accepted values ", - "are 'rust', 'rust_non_exhaustive', 'bitfield', 'consts',", - "'moduleconsts', and 'newtype'." - ), - )), - } - } -} - -/// A helper type to construct different enum variations. -enum EnumBuilder<'a> { - Rust { - codegen_depth: usize, - attrs: Vec, - ident: Ident, - tokens: proc_macro2::TokenStream, - emitted_any_variants: bool, - }, - NewType { - codegen_depth: usize, - canonical_name: &'a str, - tokens: proc_macro2::TokenStream, - is_bitfield: bool, - }, - Consts { - repr: proc_macro2::TokenStream, - variants: Vec, - codegen_depth: usize, - }, - ModuleConsts { - codegen_depth: usize, - module_name: &'a str, - module_items: Vec, - }, -} - -impl<'a> EnumBuilder<'a> { - /// Returns the depth of the code generation for a variant of this enum. - fn codegen_depth(&self) -> usize { - match *self { - EnumBuilder::Rust { codegen_depth, .. } | - EnumBuilder::NewType { codegen_depth, .. } | - EnumBuilder::ModuleConsts { codegen_depth, .. } | - EnumBuilder::Consts { codegen_depth, .. } => codegen_depth, - } - } - - /// Returns true if the builder is for a rustified enum. - fn is_rust_enum(&self) -> bool { - matches!(*self, EnumBuilder::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: proc_macro2::TokenStream, - enum_variation: EnumVariation, - enum_codegen_depth: usize, - ) -> Self { - let ident = Ident::new(name, Span::call_site()); - - match enum_variation { - EnumVariation::NewType { is_bitfield } => EnumBuilder::NewType { - codegen_depth: enum_codegen_depth, - canonical_name: name, - tokens: quote! { - #( #attrs )* - pub struct #ident (pub #repr); - }, - is_bitfield, - }, - - EnumVariation::Rust { .. } => { - // `repr` is guaranteed to be Rustified in Enum::codegen - attrs.insert(0, quote! { #[repr( #repr )] }); - let tokens = quote!(); - EnumBuilder::Rust { - codegen_depth: enum_codegen_depth + 1, - attrs, - ident, - tokens, - emitted_any_variants: false, - } - } - - EnumVariation::Consts => { - let mut variants = Vec::new(); - - variants.push(quote! { - #( #attrs )* - pub type #ident = #repr; - }); - - EnumBuilder::Consts { - repr, - variants, - codegen_depth: enum_codegen_depth, - } - } - - EnumVariation::ModuleConsts => { - let ident = Ident::new( - CONSTIFIED_ENUM_MODULE_REPR_NAME, - Span::call_site(), - ); - let type_definition = quote! { - #( #attrs )* - pub type #ident = #repr; - }; - - EnumBuilder::ModuleConsts { - codegen_depth: enum_codegen_depth + 1, - module_name: name, - module_items: vec![type_definition], - } - } - } - } - - /// Add a variant to this enum. - fn with_variant<'b>( - self, - ctx: &BindgenContext, - variant: &EnumVariant, - mangling_prefix: Option<&str>, - rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'b>, - 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) - } - 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 = - comment::preprocess(raw_comment, self.codegen_depth()); - doc = attributes::doc(comment); - } - } - - match self { - EnumBuilder::Rust { - attrs, - ident, - tokens, - emitted_any_variants: _, - codegen_depth, - } => { - let name = ctx.rust_ident(variant_name); - EnumBuilder::Rust { - attrs, - ident, - codegen_depth, - tokens: quote! { - #tokens - #doc - #name = #expr, - }, - emitted_any_variants: true, - } - } - - EnumBuilder::NewType { canonical_name, .. } => { - if ctx.options().rust_features().associated_const && is_ty_named - { - 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 ); - } - }); - } else { - let ident = ctx.rust_ident(match mangling_prefix { - Some(prefix) => { - Cow::Owned(format!("{}_{}", prefix, variant_name)) - } - None => variant_name, - }); - result.push(quote! { - #doc - pub const #ident : #rust_ty = #rust_ty ( #expr ); - }); - } - - self - } - - EnumBuilder::Consts { ref repr, .. } => { - let constant_name = match mangling_prefix { - Some(prefix) => { - Cow::Owned(format!("{}_{}", prefix, variant_name)) - } - None => variant_name, - }; - - let ty = if is_ty_named { &rust_ty } else { repr }; - - let ident = ctx.rust_ident(constant_name); - result.push(quote! { - #doc - pub const #ident : #ty = #expr ; - }); - - self - } - EnumBuilder::ModuleConsts { - codegen_depth, - module_name, - mut module_items, - } => { - 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 ; - }); - - EnumBuilder::ModuleConsts { - module_name, - module_items, - codegen_depth, - } - } - } - } - - fn build<'b>( - self, - ctx: &BindgenContext, - rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'b>, - ) -> 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 - }; - - quote! { - #( #attrs )* - pub enum #ident { - #variants - } - } - } - EnumBuilder::NewType { - canonical_name, - tokens, - is_bitfield, - .. - } => { - 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) - } - } - }); - - result.push(quote! { - impl ::#prefix::ops::BitOrAssign for #rust_ty { - #[inline] - fn bitor_assign(&mut self, rhs: #rust_ty) { - self.0 |= rhs.0; - } - } - }); - - result.push(quote! { - impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty { - type Output = Self; - - #[inline] - fn bitand(self, other: Self) -> Self { - #rust_ty_name(self.0 & other.0) - } - } - }); - - result.push(quote! { - impl ::#prefix::ops::BitAndAssign for #rust_ty { - #[inline] - fn bitand_assign(&mut self, rhs: #rust_ty) { - self.0 &= rhs.0; - } - } - }); - - tokens - } - EnumBuilder::Consts { variants, .. } => quote! { #( #variants )* }, - EnumBuilder::ModuleConsts { - module_items, - module_name, - .. - } => { - let ident = ctx.rust_ident(module_name); - quote! { - pub mod #ident { - #( #module_items )* - } - } - } - } - } -} - -impl CodeGenerator for Enum { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - debug!("::codegen: item = {:?}", item); - debug_assert!(item.is_enabled_for_codegen(ctx)); - - let name = item.canonical_name(ctx); - let ident = ctx.rust_ident(&name); - let enum_ty = item.expect_type(); - let layout = enum_ty.layout(ctx); - let variation = self.computed_enum_variation(ctx, item); - - let repr_translated; - let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) { - Some(repr) - if !ctx.options().translate_enum_integer_types && - !variation.is_rust() => - { - repr - } - repr => { - // An enum's integer type is translated to a native Rust - // integer type in 3 cases: - // * the enum is Rustified and we need a translated type for - // the repr attribute - // * 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() { - 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 - } - }; - - let signed = kind.is_signed(); - let size = layout - .map(|l| l.size) - .or_else(|| kind.known_size()) - .unwrap_or(0); - - let translated = match (signed, size) { - (true, 1) => IntKind::I8, - (false, 1) => IntKind::U8, - (true, 2) => IntKind::I16, - (false, 2) => IntKind::U16, - (true, 4) => IntKind::I32, - (false, 4) => IntKind::U32, - (true, 8) => IntKind::I64, - (false, 8) => IntKind::U64, - _ => { - warn!( - "invalid enum decl: signed: {}, size: {}", - signed, size - ); - IntKind::I32 - } - }; - - repr_translated = - Type::new(None, None, TypeKind::Int(translated), false); - &repr_translated - } - }; - - 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)); - } - - if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) - { - attrs.push(attributes::must_use()); - } - - if !variation.is_const() { - let mut derives = derives_of_item(item, ctx); - // For backwards compat, enums always derive - // Clone/Eq/PartialEq/Hash, even if we don't generate those by - // default. - derives.insert( - DerivableTraits::CLONE | - DerivableTraits::HASH | - DerivableTraits::PARTIAL_EQ | - DerivableTraits::EQ, - ); - let mut derives: Vec<_> = derives.into(); - for derive in item.annotations().derives().iter() { - if !derives.contains(&derive.as_str()) { - derives.push(derive); - } - } - - // The custom derives callback may return a list of derive attributes; - // add them to the end of the list. - let custom_derives; - if let Some(cb) = &ctx.options().parse_callbacks { - custom_derives = cb.add_derives(&name); - // 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())); - }; - - attrs.push(attributes::derives(&derives)); - } - - fn add_constant<'a>( - ctx: &BindgenContext, - enum_: &Type, - // Only to avoid recomputing every time. - enum_canonical_name: &Ident, - // May be the same as "variant" if it's because the - // enum is unnamed and we still haven't seen the - // value. - variant_name: &Ident, - referenced_name: &Ident, - enum_rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'a>, - ) { - let constant_name = if enum_.name().is_some() { - if ctx.options().prepend_enum_name { - format!("{}_{}", enum_canonical_name, variant_name) - } else { - format!("{}", variant_name) - } - } else { - format!("{}", variant_name) - }; - let constant_name = ctx.rust_ident(constant_name); - - result.push(quote! { - pub const #constant_name : #enum_rust_ty = - #enum_canonical_name :: #referenced_name ; - }); - } - - let repr = repr.to_rust_ty_or_opaque(ctx, item); - - let mut builder = EnumBuilder::new( - &name, - attrs, - repr, - variation, - item.codegen_depth(ctx), - ); - - // A map where we keep a value -> variant relation. - let mut seen_values = HashMap::<_, Ident>::default(); - let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &()); - let is_toplevel = item.is_toplevel(ctx); - - // Used to mangle the constants we generate in the unnamed-enum case. - let parent_canonical_name = if is_toplevel { - None - } else { - Some(item.parent_id().canonical_name(ctx)) - }; - - let constant_mangling_prefix = if ctx.options().prepend_enum_name { - if enum_ty.name().is_none() { - parent_canonical_name.as_deref() - } else { - Some(&*name) - } - } else { - None - }; - - // NB: We defer the creation of constified variants, in case we find - // another variant with the same value (which is the common thing to - // do). - let mut constified_variants = VecDeque::new(); - - let mut iter = self.variants().iter().peekable(); - while let Some(variant) = - iter.next().or_else(|| constified_variants.pop_front()) - { - if variant.hidden() { - continue; - } - - if variant.force_constification() && iter.peek().is_some() { - constified_variants.push_back(variant); - continue; - } - - 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(); - - 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 - { - let enum_canonical_name = &ident; - let variant_name = - ctx.rust_ident_raw(&*mangled_name); - result.push(quote! { - impl #enum_rust_ty { - pub const #variant_name : #enum_rust_ty = - #enum_canonical_name :: #existing_variant_name ; - } - }); - } else { - add_constant( - ctx, - enum_ty, - &ident, - &Ident::new(&*mangled_name, Span::call_site()), - existing_variant_name, - enum_rust_ty.clone(), - result, - ); - } - } else { - builder = builder.with_variant( - ctx, - variant, - constant_mangling_prefix, - enum_rust_ty.clone(), - result, - enum_ty.name().is_some(), - ); - } - } - Entry::Vacant(entry) => { - builder = builder.with_variant( - ctx, - variant, - constant_mangling_prefix, - enum_rust_ty.clone(), - result, - enum_ty.name().is_some(), - ); - - let variant_name = ctx.rust_ident(variant.name()); - - // If it's an unnamed enum, or constification is enforced, - // we also generate a constant so it can be properly - // accessed. - if (variation.is_rust() && enum_ty.name().is_none()) || - variant.force_constification() - { - let mangled_name = if is_toplevel { - variant_name.clone() - } else { - let parent_name = - parent_canonical_name.as_ref().unwrap(); - - Ident::new( - &format!("{}_{}", parent_name, variant_name), - Span::call_site(), - ) - }; - - add_constant( - ctx, - enum_ty, - &ident, - &mangled_name, - &variant_name, - enum_rust_ty.clone(), - result, - ); - } - - entry.insert(variant_name); - } - } - } - - let item = builder.build(ctx, enum_rust_ty, result); - result.push(item); - } -} - -/// Enum for the default type of macro constants. -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum MacroTypeVariation { - /// Use i32 or i64 - Signed, - /// Use u32 or u64 - Unsigned, -} - -impl MacroTypeVariation { - /// Convert a `MacroTypeVariation` to its str representation. - pub fn as_str(&self) -> &str { - match self { - MacroTypeVariation::Signed => "signed", - MacroTypeVariation::Unsigned => "unsigned", - } - } -} - -impl Default for MacroTypeVariation { - fn default() -> MacroTypeVariation { - MacroTypeVariation::Unsigned - } -} - -impl std::str::FromStr for MacroTypeVariation { - type Err = std::io::Error; - - /// Create a `MacroTypeVariation` from a string. - fn from_str(s: &str) -> Result { - match s { - "signed" => Ok(MacroTypeVariation::Signed), - "unsigned" => Ok(MacroTypeVariation::Unsigned), - _ => Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - concat!( - "Got an invalid MacroTypeVariation. Accepted values ", - "are 'signed' and 'unsigned'" - ), - )), - } - } -} - -/// Enum for how aliases should be translated. -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum AliasVariation { - /// Convert to regular Rust alias - 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 - NewTypeDeref, -} - -impl AliasVariation { - /// Convert an `AliasVariation` to its str representation. - pub fn as_str(&self) -> &str { - match self { - AliasVariation::TypeAlias => "type_alias", - AliasVariation::NewType => "new_type", - AliasVariation::NewTypeDeref => "new_type_deref", - } - } -} - -impl Default for AliasVariation { - fn default() -> AliasVariation { - AliasVariation::TypeAlias - } -} - -impl std::str::FromStr for AliasVariation { - type Err = std::io::Error; - - /// Create an `AliasVariation` from a string. - fn from_str(s: &str) -> Result { - match s { - "type_alias" => Ok(AliasVariation::TypeAlias), - "new_type" => Ok(AliasVariation::NewType), - "new_type_deref" => Ok(AliasVariation::NewTypeDeref), - _ => Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - concat!( - "Got an invalid AliasVariation. Accepted values ", - "are 'type_alias', 'new_type', and 'new_type_deref'" - ), - )), - } - } -} - -/// Fallible conversion to an opaque blob. -/// -/// Implementors of this trait should provide the `try_get_layout` method to -/// fallibly get this thing's layout, which the provided `try_to_opaque` trait -/// method will use to convert the `Layout` into an opaque blob Rust type. -trait TryToOpaque { - type Extra; - - /// Get the layout for this thing, if one is available. - fn try_get_layout( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> error::Result; - - /// Do not override this provided trait method. - fn try_to_opaque( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> error::Result { - self.try_get_layout(ctx, extra) - .map(|layout| helpers::blob(ctx, layout)) - } -} - -/// Infallible conversion of an IR thing to an opaque blob. -/// -/// The resulting layout is best effort, and is unfortunately not guaranteed to -/// be correct. When all else fails, we fall back to a single byte layout as a -/// last resort, because C++ does not permit zero-sized types. See the note in -/// the `ToRustTyOrOpaque` doc comment about fallible versus infallible traits -/// and when each is appropriate. -/// -/// Don't implement this directly. Instead implement `TryToOpaque`, and then -/// leverage the blanket impl for this trait. -trait ToOpaque: TryToOpaque { - fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout { - self.try_get_layout(ctx, extra) - .unwrap_or_else(|_| Layout::for_size(ctx, 1)) - } - - fn to_opaque( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> proc_macro2::TokenStream { - let layout = self.get_layout(ctx, extra); - helpers::blob(ctx, layout) - } -} - -impl ToOpaque for T where T: TryToOpaque {} - -/// Fallible conversion from an IR thing to an *equivalent* Rust type. -/// -/// If the C/C++ construct represented by the IR thing cannot (currently) be -/// represented in Rust (for example, instantiations of templates with -/// const-value generic parameters) then the impl should return an `Err`. It -/// should *not* attempt to return an opaque blob with the correct size and -/// alignment. That is the responsibility of the `TryToOpaque` trait. -trait TryToRustTy { - type Extra; - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> error::Result; -} - -/// Fallible conversion to a Rust type or an opaque blob with the correct size -/// and alignment. -/// -/// Don't implement this directly. Instead implement `TryToRustTy` and -/// `TryToOpaque`, and then leverage the blanket impl for this trait below. -trait TryToRustTyOrOpaque: TryToRustTy + TryToOpaque { - type Extra; - - fn try_to_rust_ty_or_opaque( - &self, - ctx: &BindgenContext, - extra: &::Extra, - ) -> error::Result; -} - -impl TryToRustTyOrOpaque for T -where - T: TryToRustTy + TryToOpaque, -{ - type Extra = E; - - fn try_to_rust_ty_or_opaque( - &self, - ctx: &BindgenContext, - extra: &E, - ) -> 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)) - } else { - Err(error::Error::NoLayoutForOpaqueBlob) - } - }) - } -} - -/// Infallible conversion to a Rust type, or an opaque blob with a best effort -/// of correct size and alignment. -/// -/// Don't implement this directly. Instead implement `TryToRustTy` and -/// `TryToOpaque`, and then leverage the blanket impl for this trait below. -/// -/// ### 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 -/// 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 -/// `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. -trait ToRustTyOrOpaque: TryToRustTy + ToOpaque { - type Extra; - - fn to_rust_ty_or_opaque( - &self, - ctx: &BindgenContext, - extra: &::Extra, - ) -> proc_macro2::TokenStream; -} - -impl ToRustTyOrOpaque for T -where - T: TryToRustTy + ToOpaque, -{ - type Extra = E; - - fn to_rust_ty_or_opaque( - &self, - ctx: &BindgenContext, - extra: &E, - ) -> proc_macro2::TokenStream { - self.try_to_rust_ty(ctx, extra) - .unwrap_or_else(|_| self.to_opaque(ctx, extra)) - } -} - -impl TryToOpaque for T -where - T: Copy + Into, -{ - type Extra = (); - - fn try_get_layout( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - ctx.resolve_item((*self).into()).try_get_layout(ctx, &()) - } -} - -impl TryToRustTy for T -where - T: Copy + Into, -{ - type Extra = (); - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - ctx.resolve_item((*self).into()).try_to_rust_ty(ctx, &()) - } -} - -impl TryToOpaque for Item { - type Extra = (); - - fn try_get_layout( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - self.kind().expect_type().try_get_layout(ctx, self) - } -} - -impl TryToRustTy for Item { - type Extra = (); - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - self.kind().expect_type().try_to_rust_ty(ctx, self) - } -} - -impl TryToOpaque for Type { - type Extra = Item; - - fn try_get_layout( - &self, - ctx: &BindgenContext, - _: &Item, - ) -> error::Result { - self.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob) - } -} - -impl TryToRustTy for Type { - type Extra = Item; - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - item: &Item, - ) -> error::Result { - use self::helpers::ast_ty::*; - - match *self.kind() { - TypeKind::Void => Ok(c_void(ctx)), - // TODO: we should do something smart with nullptr, or maybe *const - // c_void is enough? - TypeKind::NullPtr => Ok(c_void(ctx).to_ptr(true)), - TypeKind::Int(ik) => { - match ik { - IntKind::Bool => Ok(quote! { bool }), - IntKind::Char { .. } => Ok(raw_type(ctx, "c_char")), - IntKind::SChar => Ok(raw_type(ctx, "c_schar")), - IntKind::UChar => Ok(raw_type(ctx, "c_uchar")), - IntKind::Short => Ok(raw_type(ctx, "c_short")), - IntKind::UShort => Ok(raw_type(ctx, "c_ushort")), - IntKind::Int => Ok(raw_type(ctx, "c_int")), - IntKind::UInt => Ok(raw_type(ctx, "c_uint")), - IntKind::Long => Ok(raw_type(ctx, "c_long")), - IntKind::ULong => Ok(raw_type(ctx, "c_ulong")), - IntKind::LongLong => Ok(raw_type(ctx, "c_longlong")), - IntKind::ULongLong => Ok(raw_type(ctx, "c_ulonglong")), - IntKind::WChar => { - let layout = self - .layout(ctx) - .expect("Couldn't compute wchar_t's layout?"); - let ty = Layout::known_type_for_size(ctx, layout.size) - .expect("Non-representable wchar_t?"); - let ident = ctx.rust_ident_raw(ty); - Ok(quote! { #ident }) - } - - IntKind::I8 => Ok(quote! { i8 }), - IntKind::U8 => Ok(quote! { u8 }), - IntKind::I16 => Ok(quote! { i16 }), - IntKind::U16 => Ok(quote! { u16 }), - IntKind::I32 => Ok(quote! { i32 }), - IntKind::U32 => Ok(quote! { u32 }), - IntKind::I64 => Ok(quote! { i64 }), - IntKind::U64 => Ok(quote! { u64 }), - IntKind::Custom { name, .. } => { - Ok(proc_macro2::TokenStream::from_str(name).unwrap()) - } - IntKind::U128 => { - Ok(if ctx.options().rust_features.i128_and_u128 { - quote! { u128 } - } else { - // Best effort thing, but wrong alignment - // unfortunately. - quote! { [u64; 2] } - }) - } - IntKind::I128 => { - Ok(if ctx.options().rust_features.i128_and_u128 { - quote! { i128 } - } else { - quote! { [u64; 2] } - }) - } - } - } - TypeKind::Float(fk) => { - Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))) - } - TypeKind::Complex(fk) => { - let float_path = - float_kind_rust_type(ctx, fk, self.layout(ctx)); - - ctx.generated_bindgen_complex(); - Ok(if ctx.options().enable_cxx_namespaces { - quote! { - root::__BindgenComplex<#float_path> - } - } else { - quote! { - __BindgenComplex<#float_path> - } - }) - } - TypeKind::Function(ref fs) => { - // We can't rely on the sizeof(Option>) == - // sizeof(NonZero<_>) optimization with opaque blobs (because - // they aren't NonZero), so don't *ever* use an or_opaque - // variant here. - let ty = fs.try_to_rust_ty(ctx, &())?; - - let prefix = ctx.trait_prefix(); - Ok(quote! { - ::#prefix::option::Option<#ty> - }) - } - TypeKind::Array(item, len) | TypeKind::Vector(item, len) => { - let ty = item.try_to_rust_ty(ctx, &())?; - Ok(quote! { - [ #ty ; #len ] - }) - } - TypeKind::Enum(..) => { - let path = item.namespace_aware_canonical_path(ctx); - let path = proc_macro2::TokenStream::from_str(&path.join("::")) - .unwrap(); - Ok(quote!(#path)) - } - TypeKind::TemplateInstantiation(ref inst) => { - inst.try_to_rust_ty(ctx, item) - } - TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), - TypeKind::TemplateAlias(..) | - TypeKind::Alias(..) | - TypeKind::BlockPointer(..) => { - if self.is_block_pointer() && !ctx.options().generate_block { - let void = c_void(ctx); - return Ok(void.to_ptr(/* is_const = */ false)); - } - - if item.is_opaque(ctx, &()) && - item.used_template_params(ctx) - .into_iter() - .any(|param| param.is_template_param(ctx, &())) - { - self.try_to_opaque(ctx, item) - } else if let Some(ty) = self - .name() - .and_then(|name| utils::type_from_named(ctx, name)) - { - Ok(ty) - } else { - utils::build_path(item, ctx) - } - } - TypeKind::Comp(ref info) => { - let template_params = item.all_template_params(ctx); - if info.has_non_type_template_params() || - (item.is_opaque(ctx, &()) && !template_params.is_empty()) - { - return self.try_to_opaque(ctx, item); - } - - utils::build_path(item, ctx) - } - TypeKind::Opaque => self.try_to_opaque(ctx, item), - TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { - let is_const = ctx.resolve_type(inner).is_const(); - - let inner = - inner.into_resolver().through_type_refs().resolve(ctx); - let inner_ty = inner.expect_type(); - - let is_objc_pointer = - matches!(inner_ty.kind(), TypeKind::ObjCInterface(..)); - - // Regardless if we can properly represent the inner type, we - // should always generate a proper pointer here, so use - // infallible conversion of the inner type. - let mut ty = inner.to_rust_ty_or_opaque(ctx, &()); - ty.append_implicit_template_params(ctx, inner); - - // Avoid the first function pointer level, since it's already - // represented in Rust. - if inner_ty.canonical_type(ctx).is_function() || is_objc_pointer - { - Ok(ty) - } else { - Ok(ty.to_ptr(is_const)) - } - } - TypeKind::TypeParam => { - let name = item.canonical_name(ctx); - let ident = ctx.rust_ident(&name); - Ok(quote! { - #ident - }) - } - TypeKind::ObjCSel => Ok(quote! { - objc::runtime::Sel - }), - TypeKind::ObjCId => Ok(quote! { - id - }), - TypeKind::ObjCInterface(ref interface) => { - let name = ctx.rust_ident(interface.name()); - Ok(quote! { - #name - }) - } - ref u @ TypeKind::UnresolvedTypeRef(..) => { - unreachable!("Should have been resolved after parsing {:?}!", u) - } - } - } -} - -impl TryToOpaque for TemplateInstantiation { - type Extra = Item; - - fn try_get_layout( - &self, - ctx: &BindgenContext, - item: &Item, - ) -> error::Result { - item.expect_type() - .layout(ctx) - .ok_or(error::Error::NoLayoutForOpaqueBlob) - } -} - -impl TryToRustTy for TemplateInstantiation { - type Extra = Item; - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - item: &Item, - ) -> error::Result { - if self.is_opaque(ctx, item) { - return Err(error::Error::InstantiationOfOpaqueType); - } - - let def = self - .template_definition() - .into_resolver() - .through_type_refs() - .resolve(ctx); - - let mut ty = quote! {}; - let def_path = def.namespace_aware_canonical_path(ctx); - ty.append_separated( - def_path.into_iter().map(|p| ctx.rust_ident(p)), - quote!(::), - ); - - let def_params = def.self_template_params(ctx); - if def_params.is_empty() { - // This can happen if we generated an opaque type for a partial - // template specialization, and we've hit an instantiation of - // that partial specialization. - extra_assert!(def.is_opaque(ctx, &())); - return Err(error::Error::InstantiationOfOpaqueType); - } - - // TODO: If the definition type is a template class/struct - // definition's member template definition, it could rely on - // generic template parameters from its outer template - // class/struct. When we emit bindings for it, it could require - // *more* type arguments than we have here, and we will need to - // reconstruct them somehow. We don't have any means of doing - // that reconstruction at this time. - - let template_args = self - .template_arguments() - .iter() - .zip(def_params.iter()) - // Only pass type arguments for the type parameters that - // the def uses. - .filter(|&(_, param)| ctx.uses_template_parameter(def.id(), *param)) - .map(|(arg, _)| { - let arg = arg.into_resolver().through_type_refs().resolve(ctx); - let mut ty = arg.try_to_rust_ty(ctx, &())?; - ty.append_implicit_template_params(ctx, arg); - Ok(ty) - }) - .collect::>>()?; - - if template_args.is_empty() { - return Ok(ty); - } - - Ok(quote! { - #ty < #( #template_args ),* > - }) - } -} - -impl TryToRustTy for FunctionSig { - type Extra = (); - - fn try_to_rust_ty( - &self, - ctx: &BindgenContext, - _: &(), - ) -> error::Result { - // TODO: we might want to consider ignoring the reference return value. - let ret = utils::fnsig_return_ty(ctx, self); - let arguments = utils::fnsig_arguments(ctx, self); - let abi = self.abi(); - - match abi { - Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => { - warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target"); - Ok(proc_macro2::TokenStream::new()) - } - _ => Ok(quote! { - unsafe extern #abi fn ( #( #arguments ),* ) #ret - }), - } - } -} - -impl CodeGenerator for Function { - type Extra = Item; - - /// If we've actually generated the symbol, the number of times we've seen - /// it. - type Return = Option; - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) -> Self::Return { - debug!("::codegen: item = {:?}", item); - debug_assert!(item.is_enabled_for_codegen(ctx)); - - // We can't currently do anything with Internal functions so just - // avoid generating anything for them. - match self.linkage() { - Linkage::Internal => return None, - Linkage::External => {} - } - - // Pure virtual methods have no actual symbol, so we can't generate - // something meaningful for them. - match self.kind() { - FunctionKind::Method(ref method_kind) - if method_kind.is_pure_virtual() => - { - return None; - } - _ => {} - } - - // Similar to static member variables in a class template, we can't - // generate bindings to template functions, because the set of - // instantiations is open ended and we have no way of knowing which - // monomorphizations actually exist. - if !item.all_template_params(ctx).is_empty() { - return None; - } - - let name = self.name(); - let mut canonical_name = item.canonical_name(ctx); - let mangled_name = self.mangled_name(); - - { - let seen_symbol_name = mangled_name.unwrap_or(&canonical_name); - - // TODO: Maybe warn here if there's a type/argument mismatch, or - // something? - if result.seen_function(seen_symbol_name) { - return None; - } - result.saw_function(seen_symbol_name); - } - - 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 args = utils::fnsig_arguments(ctx, signature); - let ret = utils::fnsig_return_ty(ctx, signature); - - let mut attributes = vec![]; - - if signature.must_use() && - ctx.options().rust_features().must_use_function - { - attributes.push(attributes::must_use()); - } - - if let Some(comment) = item.comment(ctx) { - attributes.push(attributes::doc(comment)); - } - - let abi = match signature.abi() { - Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => { - warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target"); - return None; - } - Abi::Win64 if signature.is_variadic() => { - warn!("Skipping variadic function with Win64 ABI that isn't supported"); - return None; - } - Abi::Unknown(unknown_abi) => { - panic!( - "Invalid or unknown abi {:?} for function {:?} ({:?})", - unknown_abi, canonical_name, self - ); - } - abi => abi, - }; - - // Handle overloaded functions by giving each overload its own unique - // suffix. - let times_seen = result.overload_number(&canonical_name); - if times_seen > 0 { - write!(&mut canonical_name, "{}", times_seen).unwrap(); - } - - let link_name = mangled_name.unwrap_or(name); - if !utils::names_will_be_identical_after_mangling( - &canonical_name, - link_name, - Some(abi), - ) { - attributes.push(attributes::link_name(link_name)); - } - - // 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 ident = ctx.rust_ident(canonical_name); - let tokens = quote! { - #wasm_link_attribute - extern #abi { - #(#attributes)* - pub fn #ident ( #( #args ),* ) #ret; - } - }; - - // If we're doing dynamic binding generation, add to the dynamic items. - if ctx.options().dynamic_library_name.is_some() && - self.kind() == FunctionKind::Function - { - let args_identifiers = - utils::fnsig_argument_identifiers(ctx, signature); - let return_item = ctx.resolve_item(signature.return_type()); - let ret_ty = match *return_item.kind().expect_type().kind() { - TypeKind::Void => quote! {()}, - _ => return_item.to_rust_ty_or_opaque(ctx, &()), - }; - result.dynamic_items().push( - ident, - abi, - signature.is_variadic(), - ctx.options().dynamic_link_require_all, - args, - args_identifiers, - ret, - ret_ty, - ); - } else { - result.push(tokens); - } - Some(times_seen) - } -} - -fn objc_method_codegen( - ctx: &BindgenContext, - method: &ObjCMethod, - class_name: Option<&str>, - prefix: &str, -) -> proc_macro2::TokenStream { - let signature = method.signature(); - let fn_args = utils::fnsig_arguments(ctx, signature); - let fn_ret = utils::fnsig_return_ty(ctx, signature); - - let sig = if method.is_class_method() { - let fn_args = fn_args.clone(); - quote! { - ( #( #fn_args ),* ) #fn_ret - } - } else { - let fn_args = fn_args.clone(); - let args = iter::once(quote! { &self }).chain(fn_args.into_iter()); - quote! { - ( #( #args ),* ) #fn_ret - } - }; - - let methods_and_args = method.format_method_call(&fn_args); - - let body = if method.is_class_method() { - let class_name = ctx.rust_ident( - class_name - .expect("Generating a class method without class name?") - .to_owned(), - ); - quote! { - msg_send!(class!(#class_name), #methods_and_args) - } - } else { - quote! { - msg_send!(*self, #methods_and_args) - } - }; - - let method_name = - ctx.rust_ident(format!("{}{}", prefix, method.rust_name())); - - quote! { - unsafe fn #method_name #sig where ::Target: objc::Message + Sized { - #body - } - } -} - -impl CodeGenerator for ObjCInterface { - type Extra = Item; - type Return = (); - - fn codegen<'a>( - &self, - ctx: &BindgenContext, - result: &mut CodegenResult<'a>, - item: &Item, - ) { - debug_assert!(item.is_enabled_for_codegen(ctx)); - - let mut impl_items = vec![]; - - for method in self.methods() { - let impl_item = objc_method_codegen(ctx, method, None, ""); - impl_items.push(impl_item); - } - - for class_method in self.class_methods() { - let ambiquity = self - .methods() - .iter() - .map(|m| m.rust_name()) - .any(|x| x == class_method.rust_name()); - let prefix = if ambiquity { "class_" } else { "" }; - let impl_item = objc_method_codegen( - ctx, - class_method, - Some(self.name()), - prefix, - ); - impl_items.push(impl_item); - } - - let trait_name = ctx.rust_ident(self.rust_name()); - let trait_constraints = quote! { - Sized + std::ops::Deref - }; - let trait_block = if self.is_template() { - let template_names: Vec = self - .template_names - .iter() - .map(|g| ctx.rust_ident(g)) - .collect(); - - quote! { - pub trait #trait_name <#(#template_names),*> : #trait_constraints { - #( #impl_items )* - } - } - } else { - quote! { - pub trait #trait_name : #trait_constraints { - #( #impl_items )* - } - } - }; - - let class_name = ctx.rust_ident(self.name()); - if !self.is_category() && !self.is_protocol() { - let struct_block = quote! { - #[repr(transparent)] - #[derive(Clone)] - pub struct #class_name(pub id); - impl std::ops::Deref for #class_name { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { - &*self.0 - } - } - } - unsafe impl objc::Message for #class_name { } - impl #class_name { - pub fn alloc() -> Self { - Self(unsafe { - msg_send!(objc::class!(#class_name), alloc) - }) - } - } - }; - result.push(struct_block); - let mut protocol_set: HashSet = Default::default(); - for protocol_id in self.conforms_to.iter() { - protocol_set.insert(*protocol_id); - let protocol_name = ctx.rust_ident( - ctx.resolve_type(protocol_id.expect_type_id(ctx)) - .name() - .unwrap(), - ); - let impl_trait = quote! { - impl #protocol_name for #class_name { } - }; - result.push(impl_trait); - } - let mut parent_class = self.parent_class; - while let Some(parent_id) = parent_class { - let parent = parent_id - .expect_type_id(ctx) - .into_resolver() - .through_type_refs() - .resolve(ctx) - .expect_type() - .kind(); - - let parent = match parent { - TypeKind::ObjCInterface(ref parent) => parent, - _ => break, - }; - parent_class = parent.parent_class; - - let parent_name = ctx.rust_ident(parent.rust_name()); - let impl_trait = if parent.is_template() { - let template_names: Vec = parent - .template_names - .iter() - .map(|g| ctx.rust_ident(g)) - .collect(); - quote! { - impl <#(#template_names :'static),*> #parent_name <#(#template_names),*> for #class_name { - } - } - } else { - quote! { - impl #parent_name for #class_name { } - } - }; - result.push(impl_trait); - for protocol_id in parent.conforms_to.iter() { - if protocol_set.insert(*protocol_id) { - let protocol_name = ctx.rust_ident( - ctx.resolve_type(protocol_id.expect_type_id(ctx)) - .name() - .unwrap(), - ); - let impl_trait = quote! { - impl #protocol_name for #class_name { } - }; - result.push(impl_trait); - } - } - if !parent.is_template() { - let parent_struct_name = parent.name(); - let child_struct_name = self.name(); - let parent_struct = ctx.rust_ident(parent_struct_name); - let from_block = quote! { - impl From<#class_name> for #parent_struct { - fn from(child: #class_name) -> #parent_struct { - #parent_struct(child.0) - } - } - }; - result.push(from_block); - - let error_msg = format!( - "This {} cannot be downcasted to {}", - parent_struct_name, child_struct_name - ); - let try_into_block = quote! { - impl std::convert::TryFrom<#parent_struct> for #class_name { - type Error = &'static str; - fn try_from(parent: #parent_struct) -> Result<#class_name, Self::Error> { - let is_kind_of : bool = unsafe { msg_send!(parent, isKindOfClass:class!(#class_name))}; - if is_kind_of { - Ok(#class_name(parent.0)) - } else { - Err(#error_msg) - } - } - } - }; - result.push(try_into_block); - } - } - } - - if !self.is_protocol() { - let impl_block = if self.is_template() { - let template_names: Vec = self - .template_names - .iter() - .map(|g| ctx.rust_ident(g)) - .collect(); - quote! { - impl <#(#template_names :'static),*> #trait_name <#(#template_names),*> for #class_name { - } - } - } else { - quote! { - impl #trait_name for #class_name { - } - } - }; - result.push(impl_block); - } - - result.push(trait_block); - result.saw_objc(); - } -} - -pub(crate) fn codegen( - context: BindgenContext, -) -> (Vec, BindgenOptions) { - context.gen(|context| { - let _t = context.timer("codegen"); - let counter = Cell::new(0); - let mut result = CodegenResult::new(&counter); - - debug!("codegen: {:?}", context.options()); - - if context.options().emit_ir { - let codegen_items = context.codegen_items(); - for (id, item) in context.items() { - if codegen_items.contains(&id) { - println!("ir: {:?} = {:#?}", id, item); - } - } - } - - 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 - ), - Err(e) => warn!("{}", e), - } - } - - if let Some(spec) = context.options().depfile.as_ref() { - match spec.write(context.deps()) { - Ok(()) => info!( - "Your depfile was generated successfully into: {}", - spec.depfile_path.display() - ), - Err(e) => warn!("{}", e), - } - } - - context.resolve_item(context.root_module()).codegen( - context, - &mut result, - &(), - ); - - 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); - result.push(dynamic_items_tokens); - } - - result.items - }) -} - -pub mod utils { - use super::{error, ToRustTyOrOpaque}; - use crate::ir::context::BindgenContext; - use crate::ir::function::{Abi, FunctionSig}; - use crate::ir::item::{Item, ItemCanonicalPath}; - use crate::ir::ty::TypeKind; - use proc_macro2; - use std::borrow::Cow; - use std::mem; - use std::str::FromStr; - - pub fn prepend_bitfield_unit_type( - ctx: &BindgenContext, - result: &mut Vec, - ) { - let bitfield_unit_src = include_str!("./bitfield_unit.rs"); - let bitfield_unit_src = if ctx.options().rust_features().min_const_fn { - Cow::Borrowed(bitfield_unit_src) - } else { - Cow::Owned(bitfield_unit_src.replace("const fn ", "fn ")) - }; - let bitfield_unit_type = - proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap(); - let bitfield_unit_type = quote!(#bitfield_unit_type); - - let items = vec![bitfield_unit_type]; - let old_items = mem::replace(result, items); - result.extend(old_items); - } - - pub fn prepend_objc_header( - ctx: &BindgenContext, - result: &mut Vec, - ) { - let use_objc = if ctx.options().objc_extern_crate { - quote! { - #[macro_use] - extern crate objc; - } - } else { - quote! { - use objc; - } - }; - - let id_type = quote! { - #[allow(non_camel_case_types)] - pub type id = *mut objc::runtime::Object; - }; - - let items = vec![use_objc, id_type]; - let old_items = mem::replace(result, items); - result.extend(old_items.into_iter()); - } - - pub fn prepend_block_header( - ctx: &BindgenContext, - result: &mut Vec, - ) { - let use_block = if ctx.options().block_extern_crate { - quote! { - extern crate block; - } - } else { - quote! { - use block; - } - }; - - let items = vec![use_block]; - let old_items = mem::replace(result, items); - result.extend(old_items.into_iter()); - } - - pub fn prepend_union_types( - ctx: &BindgenContext, - result: &mut Vec, - ) { - let prefix = ctx.trait_prefix(); - - // 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 { - quote! { const fn } - } else { - quote! { fn } - }; - - // TODO(emilio): The fmt::Debug impl could be way nicer with - // std::intrinsics::type_name, but... - let union_field_decl = quote! { - #[repr(C)] - pub struct __BindgenUnionField(::#prefix::marker::PhantomData); - }; - - let union_field_impl = quote! { - impl __BindgenUnionField { - #[inline] - pub #const_fn new() -> Self { - __BindgenUnionField(::#prefix::marker::PhantomData) - } - - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::#prefix::mem::transmute(self) - } - - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::#prefix::mem::transmute(self) - } - } - }; - - let union_field_default_impl = quote! { - impl ::#prefix::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } - } - }; - - let union_field_clone_impl = quote! { - impl ::#prefix::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - Self::new() - } - } - }; - - let union_field_copy_impl = quote! { - impl ::#prefix::marker::Copy for __BindgenUnionField {} - }; - - let union_field_debug_impl = quote! { - impl ::#prefix::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>) - -> ::#prefix::fmt::Result { - fmt.write_str("__BindgenUnionField") - } - } - }; - - // The actual memory of the filed will be hashed, so that's why these - // field doesn't do anything with the hash. - let union_field_hash_impl = quote! { - impl ::#prefix::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) { - } - } - }; - - let union_field_partialeq_impl = quote! { - impl ::#prefix::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } - } - }; - - let union_field_eq_impl = quote! { - impl ::#prefix::cmp::Eq for __BindgenUnionField { - } - }; - - let items = vec![ - union_field_decl, - union_field_impl, - union_field_default_impl, - union_field_clone_impl, - union_field_copy_impl, - union_field_debug_impl, - union_field_hash_impl, - union_field_partialeq_impl, - union_field_eq_impl, - ]; - - let old_items = mem::replace(result, items); - result.extend(old_items.into_iter()); - } - - pub fn prepend_incomplete_array_types( - ctx: &BindgenContext, - result: &mut Vec, - ) { - let prefix = ctx.trait_prefix(); - - // 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 { - quote! { const fn } - } else { - quote! { fn } - }; - - let incomplete_array_decl = quote! { - #[repr(C)] - #[derive(Default)] - pub struct __IncompleteArrayField( - ::#prefix::marker::PhantomData, [T; 0]); - }; - - let incomplete_array_impl = quote! { - impl __IncompleteArrayField { - #[inline] - pub #const_fn new() -> Self { - __IncompleteArrayField(::#prefix::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] { - ::#prefix::slice::from_raw_parts(self.as_ptr(), len) - } - - #[inline] - pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len) - } - } - }; - - let incomplete_array_debug_impl = quote! { - impl ::#prefix::fmt::Debug for __IncompleteArrayField { - fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>) - -> ::#prefix::fmt::Result { - fmt.write_str("__IncompleteArrayField") - } - } - }; - - let items = vec![ - incomplete_array_decl, - incomplete_array_impl, - incomplete_array_debug_impl, - ]; - - let old_items = mem::replace(result, items); - result.extend(old_items.into_iter()); - } - - pub fn prepend_complex_type(result: &mut Vec) { - let complex_type = quote! { - #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] - #[repr(C)] - pub struct __BindgenComplex { - pub re: T, - pub im: T - } - }; - - let items = vec![complex_type]; - let old_items = mem::replace(result, items); - result.extend(old_items.into_iter()); - } - - pub fn build_path( - item: &Item, - ctx: &BindgenContext, - ) -> error::Result { - let path = item.namespace_aware_canonical_path(ctx); - let tokens = - proc_macro2::TokenStream::from_str(&path.join("::")).unwrap(); - - Ok(tokens) - } - - fn primitive_ty( - ctx: &BindgenContext, - name: &str, - ) -> proc_macro2::TokenStream { - let ident = ctx.rust_ident_raw(name); - quote! { - #ident - } - } - - pub fn type_from_named( - ctx: &BindgenContext, - name: &str, - ) -> Option { - // FIXME: We could use the inner item to check this is really a - // primitive type but, who the heck overrides these anyway? - Some(match name { - "int8_t" => primitive_ty(ctx, "i8"), - "uint8_t" => primitive_ty(ctx, "u8"), - "int16_t" => primitive_ty(ctx, "i16"), - "uint16_t" => primitive_ty(ctx, "u16"), - "int32_t" => primitive_ty(ctx, "i32"), - "uint32_t" => primitive_ty(ctx, "u32"), - "int64_t" => primitive_ty(ctx, "i64"), - "uint64_t" => primitive_ty(ctx, "u64"), - - "size_t" if ctx.options().size_t_is_usize => { - primitive_ty(ctx, "usize") - } - "uintptr_t" => primitive_ty(ctx, "usize"), - - "ssize_t" if ctx.options().size_t_is_usize => { - primitive_ty(ctx, "isize") - } - "intptr_t" | "ptrdiff_t" => primitive_ty(ctx, "isize"), - _ => return None, - }) - } - - pub fn fnsig_return_ty( - ctx: &BindgenContext, - sig: &FunctionSig, - ) -> proc_macro2::TokenStream { - let return_item = ctx.resolve_item(sig.return_type()); - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! {} - } else { - let ret_ty = return_item.to_rust_ty_or_opaque(ctx, &()); - quote! { - -> #ret_ty - } - } - } - - pub fn fnsig_arguments( - ctx: &BindgenContext, - sig: &FunctionSig, - ) -> Vec { - use super::ToPtr; - - let mut unnamed_arguments = 0; - let mut args = sig - .argument_types() - .iter() - .map(|&(ref name, ty)| { - let arg_item = ctx.resolve_item(ty); - let arg_ty = arg_item.kind().expect_type(); - - // From the C90 standard[1]: - // - // A declaration of a parameter as "array of type" shall be - // adjusted to "qualified pointer to type", where the type - // qualifiers (if any) are those specified within the [ and ] of - // the array type derivation. - // - // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html - let arg_ty = match *arg_ty.canonical_type(ctx).kind() { - TypeKind::Array(t, _) => { - let stream = - if ctx.options().array_pointers_in_arguments { - arg_ty.to_rust_ty_or_opaque(ctx, arg_item) - } else { - t.to_rust_ty_or_opaque(ctx, &()) - }; - stream.to_ptr(ctx.resolve_type(t).is_const()) - } - TypeKind::Pointer(inner) => { - let inner = ctx.resolve_item(inner); - let inner_ty = inner.expect_type(); - if let TypeKind::ObjCInterface(ref interface) = - *inner_ty.canonical_type(ctx).kind() - { - let name = ctx.rust_ident(interface.name()); - quote! { - #name - } - } else { - arg_item.to_rust_ty_or_opaque(ctx, &()) - } - } - _ => arg_item.to_rust_ty_or_opaque(ctx, &()), - }; - - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } - }; - - assert!(!arg_name.is_empty()); - let arg_name = ctx.rust_ident(arg_name); - - quote! { - #arg_name : #arg_ty - } - }) - .collect::>(); - - if sig.is_variadic() { - args.push(quote! { ... }) - } - - args - } - - pub fn fnsig_argument_identifiers( - ctx: &BindgenContext, - sig: &FunctionSig, - ) -> Vec { - let mut unnamed_arguments = 0; - let args = sig - .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) - } - }; - - assert!(!arg_name.is_empty()); - let arg_name = ctx.rust_ident(arg_name); - - quote! { - #arg_name - } - }) - .collect::>(); - - args - } - - pub fn fnsig_block( - ctx: &BindgenContext, - sig: &FunctionSig, - ) -> proc_macro2::TokenStream { - let args = sig.argument_types().iter().map(|&(_, ty)| { - let arg_item = ctx.resolve_item(ty); - - arg_item.to_rust_ty_or_opaque(ctx, &()) - }); - - let return_item = ctx.resolve_item(sig.return_type()); - let ret_ty = - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! { () } - } else { - return_item.to_rust_ty_or_opaque(ctx, &()) - }; - - quote! { - *const ::block::Block<(#(#args,)*), #ret_ty> - } - } - - // Returns true if `canonical_name` will end up as `mangled_name` at the - // machine code level, i.e. after LLVM has applied any target specific - // mangling. - pub fn names_will_be_identical_after_mangling( - canonical_name: &str, - mangled_name: &str, - call_conv: Option, - ) -> bool { - // If the mangled name and the canonical name are the same then no - // mangling can have happened between the two versions. - if canonical_name == mangled_name { - return true; - } - - // Working with &[u8] makes indexing simpler than with &str - let canonical_name = canonical_name.as_bytes(); - let mangled_name = mangled_name.as_bytes(); - - let (mangling_prefix, expect_suffix) = match call_conv { - Some(Abi::C) | - // None is the case for global variables - None => { - (b'_', false) - } - Some(Abi::Stdcall) => (b'_', true), - Some(Abi::Fastcall) => (b'@', true), - - // This is something we don't recognize, stay on the safe side - // by emitting the `#[link_name]` attribute - Some(_) => return false, - }; - - // Check that the mangled name is long enough to at least contain the - // canonical name plus the expected prefix. - if mangled_name.len() < canonical_name.len() + 1 { - return false; - } - - // Return if the mangled name does not start with the prefix expected - // for the given calling convention. - if mangled_name[0] != mangling_prefix { - return false; - } - - // Check that the mangled name contains the canonical name after the - // prefix - if &mangled_name[1..canonical_name.len() + 1] != canonical_name { - return false; - } - - // If the given calling convention also prescribes a suffix, check that - // it exists too - if expect_suffix { - let suffix = &mangled_name[canonical_name.len() + 1..]; - - // The shortest suffix is "@0" - if suffix.len() < 2 { - return false; - } - - // Check that the suffix starts with '@' and is all ASCII decimals - // after that. - if suffix[0] != b'@' || !suffix[1..].iter().all(u8::is_ascii_digit) - { - return false; - } - } else if mangled_name.len() != canonical_name.len() + 1 { - // If we don't expect a prefix but there is one, we need the - // #[link_name] attribute - return false; - } - - true - } -} diff --git a/src/deps.rs b/src/deps.rs deleted file mode 100644 index 479c396cbb..0000000000 --- a/src/deps.rs +++ /dev/null @@ -1,20 +0,0 @@ -/// Generating build depfiles from parsed bindings. -use std::{collections::BTreeSet, path::PathBuf}; - -#[derive(Debug)] -pub(crate) struct DepfileSpec { - pub output_module: String, - pub depfile_path: PathBuf, -} - -impl DepfileSpec { - pub fn write(&self, deps: &BTreeSet) -> std::io::Result<()> { - let mut buf = format!("{}:", self.output_module); - - for file in deps { - buf = format!("{} {}", buf, file); - } - - std::fs::write(&self.depfile_path, &buf) - } -} diff --git a/src/extra_assertions.rs b/src/extra_assertions.rs deleted file mode 100644 index 0888bf3969..0000000000 --- a/src/extra_assertions.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Macros for defining extra assertions that should only be checked in testing -//! and/or CI when the `testing_only_extra_assertions` feature is enabled. - -/// Simple macro that forwards to assert! when using -/// testing_only_extra_assertions. -#[macro_export] -macro_rules! extra_assert { - ( $cond:expr ) => { - if cfg!(feature = "testing_only_extra_assertions") { - assert!($cond); - } - }; - ( $cond:expr , $( $arg:tt )+ ) => { - if cfg!(feature = "testing_only_extra_assertions") { - assert!($cond, $( $arg )* ) - } - }; -} - -/// Simple macro that forwards to assert_eq! when using -/// testing_only_extra_assertions. -#[macro_export] -macro_rules! extra_assert_eq { - ( $lhs:expr , $rhs:expr ) => { - if cfg!(feature = "testing_only_extra_assertions") { - assert_eq!($lhs, $rhs); - } - }; - ( $lhs:expr , $rhs:expr , $( $arg:tt )+ ) => { - if cfg!(feature = "testing_only_extra_assertions") { - assert!($lhs, $rhs, $( $arg )* ); - } - }; -} diff --git a/src/features.rs b/src/features.rs deleted file mode 100644 index a786f07f12..0000000000 --- a/src/features.rs +++ /dev/null @@ -1,302 +0,0 @@ -//! Contains code for selecting features - -#![deny(missing_docs)] -#![deny(unused_extern_crates)] - -use std::io; -use std::str::FromStr; - -/// Define RustTarget struct definition, Default impl, and conversions -/// between RustTarget and String. -macro_rules! rust_target_def { - ( $( $( #[$attr:meta] )* => $release:ident => $value:expr; )* ) => { - /// 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. - #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Hash)] - #[allow(non_camel_case_types)] - pub enum RustTarget { - $( - $( - #[$attr] - )* - $release, - )* - } - - impl Default for RustTarget { - /// Gives the latest stable Rust version - fn default() -> RustTarget { - LATEST_STABLE_RUST - } - } - - impl FromStr for RustTarget { - type Err = io::Error; - - /// Create a `RustTarget` from a string. - /// - /// * The stable/beta versions of Rust are of the form "1.0", - /// "1.19", etc. - /// * The nightly version should be specified with "nightly". - fn from_str(s: &str) -> Result { - match s.as_ref() { - $( - stringify!($value) => Ok(RustTarget::$release), - )* - _ => Err( - io::Error::new( - io::ErrorKind::InvalidInput, - concat!( - "Got an invalid rust target. Accepted values ", - "are of the form ", - "\"1.0\" or \"nightly\"."))), - } - } - } - - impl From for String { - fn from(target: RustTarget) -> Self { - match target { - $( - RustTarget::$release => stringify!($value), - )* - }.into() - } - } - } -} - -/// Defines an array slice with all RustTarget values -macro_rules! rust_target_values_def { - ( $( $( #[$attr:meta] )* => $release:ident => $value:expr; )* ) => { - /// Strings of allowed `RustTarget` values - pub static RUST_TARGET_STRINGS: &'static [&str] = &[ - $( - stringify!($value), - )* - ]; - } -} - -/// Defines macro which takes a macro -macro_rules! rust_target_base { - ( $x_macro:ident ) => { - $x_macro!( - /// Rust stable 1.0 - => Stable_1_0 => 1.0; - /// Rust stable 1.17 - /// * Static lifetime elision ([RFC 1623](https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md)) - => Stable_1_17 => 1.17; - /// Rust stable 1.19 - /// * Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md)) - => Stable_1_19 => 1.19; - /// Rust stable 1.20 - /// * Associated constants ([PR](https://github.com/rust-lang/rust/pull/42809)) - => Stable_1_20 => 1.20; - /// Rust stable 1.21 - /// * Builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690)) - => Stable_1_21 => 1.21; - /// Rust stable 1.25 - /// * `repr(align)` ([PR](https://github.com/rust-lang/rust/pull/47006)) - => Stable_1_25 => 1.25; - /// Rust stable 1.26 - /// * [i128 / u128 support](https://doc.rust-lang.org/std/primitive.i128.html) - => Stable_1_26 => 1.26; - /// Rust stable 1.27 - /// * `must_use` attribute on functions ([PR](https://github.com/rust-lang/rust/pull/48925)) - => Stable_1_27 => 1.27; - /// Rust stable 1.28 - /// * `repr(transparent)` ([PR](https://github.com/rust-lang/rust/pull/51562)) - => Stable_1_28 => 1.28; - /// Rust stable 1.30 - /// * `const fn` support for limited cases ([PR](https://github.com/rust-lang/rust/pull/54835/) - /// * [c_void available in core](https://doc.rust-lang.org/core/ffi/enum.c_void.html) - => Stable_1_30 => 1.30; - /// Rust stable 1.33 - /// * repr(packed(N)) ([PR](https://github.com/rust-lang/rust/pull/57049)) - => Stable_1_33 => 1.33; - /// Rust stable 1.36 - /// * `MaybeUninit` instead of `mem::uninitialized()` ([PR](https://github.com/rust-lang/rust/pull/60445)) - => Stable_1_36 => 1.36; - /// Rust stable 1.40 - /// * `non_exhaustive` enums/structs ([Tracking issue](https://github.com/rust-lang/rust/issues/44109)) - => Stable_1_40 => 1.40; - /// Rust stable 1.47 - /// * `larger_arrays` ([Tracking issue](https://github.com/rust-lang/rust/pull/74060)) - => Stable_1_47 => 1.47; - /// Nightly rust - /// * `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202)) - => Nightly => nightly; - ); - } -} - -rust_target_base!(rust_target_def); -rust_target_base!(rust_target_values_def); - -/// Latest stable release of Rust -pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_47; - -/// Create RustFeatures struct definition, new(), and a getter for each field -macro_rules! rust_feature_def { - ( - $( $rust_target:ident { - $( $( #[$attr:meta] )* => $feature:ident; )* - } )* - ) => { - /// Features supported by a rust target - #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] - #[allow(missing_docs)] // Documentation should go into the relevant variants. - pub(crate) struct RustFeatures { - $( $( - $( - #[$attr] - )* - pub $feature: bool, - )* )* - } - - impl RustFeatures { - /// Gives a RustFeatures struct with all features disabled - fn new() -> Self { - RustFeatures { - $( $( - $feature: false, - )* )* - } - } - } - - impl From for RustFeatures { - fn from(rust_target: RustTarget) -> Self { - let mut features = RustFeatures::new(); - - $( - if rust_target >= RustTarget::$rust_target { - $( - features.$feature = true; - )* - } - )* - - features - } - } - } -} - -// NOTE(emilio): When adding or removing features here, make sure to update the -// documentation for the relevant variant in the rust_target_base macro -// definition. -rust_feature_def!( - Stable_1_17 { - => static_lifetime_elision; - } - Stable_1_19 { - => untagged_union; - } - Stable_1_20 { - => associated_const; - } - Stable_1_21 { - => builtin_clone_impls; - } - Stable_1_25 { - => repr_align; - } - Stable_1_26 { - => i128_and_u128; - } - Stable_1_27 { - => must_use_function; - } - Stable_1_28 { - => repr_transparent; - } - Stable_1_30 { - => min_const_fn; - => core_ffi_c_void; - } - Stable_1_33 { - => repr_packed_n; - } - Stable_1_36 { - => maybe_uninit; - } - Stable_1_40 { - => non_exhaustive; - } - Stable_1_47 { - => larger_arrays; - } - Nightly { - => thiscall_abi; - } -); - -impl Default for RustFeatures { - fn default() -> Self { - let default_rust_target: RustTarget = Default::default(); - Self::from(default_rust_target) - } -} - -#[cfg(test)] -mod test { - #![allow(unused_imports)] - 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 - ); - 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 - ); - let f_nightly = RustFeatures::from(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 - ); - } - - fn test_target(target_str: &str, target: RustTarget) { - let target_string: String = target.into(); - assert_eq!(target_str, target_string); - assert_eq!(target, RustTarget::from_str(target_str).unwrap()); - } - - #[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); - test_target("nightly", RustTarget::Nightly); - } -} diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs deleted file mode 100644 index f63458e5e7..0000000000 --- a/src/ir/analysis/derive.rs +++ /dev/null @@ -1,732 +0,0 @@ -//! Determining which types for which we cannot emit `#[derive(Trait)]`. - -use std::fmt; - -use super::{generate_dependencies, ConstrainResult, MonotoneFramework}; -use crate::ir::analysis::has_vtable::HasVtable; -use crate::ir::comp::CompKind; -use crate::ir::context::{BindgenContext, ItemId}; -use crate::ir::derive::CanDerive; -use crate::ir::function::FunctionSig; -use crate::ir::item::{IsOpaque, Item}; -use crate::ir::layout::Layout; -use crate::ir::template::TemplateParameters; -use crate::ir::traversal::{EdgeKind, Trace}; -use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; -use crate::ir::ty::{Type, TypeKind}; -use crate::{Entry, HashMap, HashSet}; - -/// Which trait to consider when doing the `CannotDerive` analysis. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum DeriveTrait { - /// The `Copy` trait. - Copy, - /// The `Debug` trait. - Debug, - /// The `Default` trait. - Default, - /// The `Hash` trait. - Hash, - /// The `PartialEq` and `PartialOrd` traits. - PartialEqOrPartialOrd, -} - -/// An analysis that finds for each IR item whether a trait cannot be derived. -/// -/// We use the monotone constraint function `cannot_derive`, defined as follows -/// for type T: -/// -/// * If T is Opaque and the layout of the type is known, get this layout as an -/// opaquetype and check whether it can derive using trivial checks. -/// -/// * If T is Array, a trait cannot be derived if the array is incomplete, -/// if the length of the array is larger than the limit (unless the trait -/// allows it), or the trait cannot be derived for the type of data the array -/// contains. -/// -/// * If T is Vector, a trait cannot be derived if the trait cannot be derived -/// for the type of data the vector contains. -/// -/// * If T is a type alias, a templated alias or an indirection to another type, -/// the trait cannot be derived if the trait cannot be derived for type T -/// refers to. -/// -/// * If T is a compound type, the trait cannot be derived if the trait cannot -/// be derived for any of its base members or fields. -/// -/// * If T is an instantiation of an abstract template definition, the trait -/// cannot be derived if any of the template arguments or template definition -/// cannot derive the trait. -/// -/// * For all other (simple) types, compiler and standard library limitations -/// dictate whether the trait is implemented. -#[derive(Debug, Clone)] -pub struct CannotDerive<'ctx> { - ctx: &'ctx BindgenContext, - - derive_trait: DeriveTrait, - - // The incremental result of this analysis's computation. - // Contains information whether particular item can derive `derive_trait` - can_derive: HashMap, - - // Dependencies saying that if a key ItemId has been inserted into the - // `cannot_derive_partialeq_or_partialord` set, then each of the ids - // in Vec need to be considered again. - // - // This is a subset of the natural IR graph with reversed edges, where we - // only include the edges from the IR graph that can affect whether a type - // can derive `derive_trait`. - dependencies: HashMap>, -} - -type EdgePredicate = fn(EdgeKind) -> bool; - -fn consider_edge_default(kind: EdgeKind) -> bool { - match kind { - // These are the only edges that can affect whether a type can derive - EdgeKind::BaseMember | - EdgeKind::Field | - EdgeKind::TypeReference | - EdgeKind::VarType | - EdgeKind::TemplateArgument | - EdgeKind::TemplateDeclaration | - EdgeKind::TemplateParameterDefinition => true, - - EdgeKind::Constructor | - EdgeKind::Destructor | - EdgeKind::FunctionReturn | - EdgeKind::FunctionParameter | - EdgeKind::InnerType | - EdgeKind::InnerVar | - EdgeKind::Method | - EdgeKind::Generic => false, - } -} - -impl<'ctx> CannotDerive<'ctx> { - fn insert>( - &mut self, - id: Id, - can_derive: CanDerive, - ) -> ConstrainResult { - let id = id.into(); - trace!( - "inserting {:?} can_derive<{}>={:?}", - id, - self.derive_trait, - can_derive - ); - - if let CanDerive::Yes = can_derive { - return ConstrainResult::Same; - } - - match self.can_derive.entry(id) { - Entry::Occupied(mut entry) => { - if *entry.get() < can_derive { - entry.insert(can_derive); - ConstrainResult::Changed - } else { - ConstrainResult::Same - } - } - Entry::Vacant(entry) => { - entry.insert(can_derive); - ConstrainResult::Changed - } - } - } - - fn constrain_type(&mut self, item: &Item, ty: &Type) -> CanDerive { - if !self.ctx.allowlisted_items().contains(&item.id()) { - let can_derive = self - .ctx - .blocklisted_type_implements_trait(item, self.derive_trait); - match can_derive { - CanDerive::Yes => trace!( - " blocklisted type explicitly implements {}", - self.derive_trait - ), - CanDerive::Manually => trace!( - " blocklisted type requires manual implementation of {}", - self.derive_trait - ), - CanDerive::No => trace!( - " cannot derive {} for blocklisted type", - self.derive_trait - ), - } - return can_derive; - } - - if self.derive_trait.not_by_name(self.ctx, item) { - trace!( - " cannot derive {} for explicitly excluded type", - self.derive_trait - ); - return CanDerive::No; - } - - trace!("ty: {:?}", ty); - if item.is_opaque(self.ctx, &()) { - if !self.derive_trait.can_derive_union() && - ty.is_union() && - self.ctx.options().rust_features().untagged_union - { - trace!( - " cannot derive {} for Rust unions", - self.derive_trait - ); - 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; - } - - match *ty.kind() { - // Handle the simple cases. These can derive traits without further - // information. - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Complex(..) | - TypeKind::Float(..) | - TypeKind::Enum(..) | - TypeKind::TypeParam | - TypeKind::UnresolvedTypeRef(..) | - TypeKind::Reference(..) | - TypeKind::ObjCInterface(..) | - TypeKind::ObjCId | - TypeKind::ObjCSel => { - return self.derive_trait.can_derive_simple(ty.kind()); - } - TypeKind::Pointer(inner) => { - let inner_type = - self.ctx.resolve_type(inner).canonical_type(self.ctx); - if let TypeKind::Function(ref sig) = *inner_type.kind() { - self.derive_trait.can_derive_fnptr(sig) - } else { - self.derive_trait.can_derive_pointer() - } - } - TypeKind::Function(ref sig) => { - self.derive_trait.can_derive_fnptr(sig) - } - - // Complex cases need more information - TypeKind::Array(t, len) => { - let inner_type = - self.can_derive.get(&t.into()).cloned().unwrap_or_default(); - if inner_type != CanDerive::Yes { - trace!( - " arrays of T for which we cannot derive {} \ - also cannot derive {}", - self.derive_trait, - self.derive_trait - ); - return CanDerive::No; - } - - if len == 0 && !self.derive_trait.can_derive_incomplete_array() - { - trace!( - " cannot derive {} for incomplete arrays", - self.derive_trait - ); - return CanDerive::No; - } - - if self.derive_trait.can_derive_large_array(self.ctx) { - trace!(" array can derive {}", self.derive_trait); - return CanDerive::Yes; - } - - if len > RUST_DERIVE_IN_ARRAY_LIMIT { - trace!( - " array is too large to derive {}, but it may be implemented", self.derive_trait - ); - return CanDerive::Manually; - } - trace!( - " array is small enough to derive {}", - self.derive_trait - ); - CanDerive::Yes - } - TypeKind::Vector(t, len) => { - let inner_type = - self.can_derive.get(&t.into()).cloned().unwrap_or_default(); - if inner_type != CanDerive::Yes { - trace!( - " vectors of T for which we cannot derive {} \ - also cannot derive {}", - self.derive_trait, - self.derive_trait - ); - return CanDerive::No; - } - assert_ne!(len, 0, "vectors cannot have zero length"); - self.derive_trait.can_derive_vector() - } - - TypeKind::Comp(ref info) => { - assert!( - !info.has_non_type_template_params(), - "The early ty.is_opaque check should have handled this case" - ); - - if !self.derive_trait.can_derive_compound_forward_decl() && - info.is_forward_declaration() - { - trace!( - " cannot derive {} for forward decls", - self.derive_trait - ); - return CanDerive::No; - } - - // NOTE: Take into account that while unions in C and C++ are copied by - // default, the may have an explicit destructor in C++, so we can't - // defer this check just for the union case. - if !self.derive_trait.can_derive_compound_with_destructor() && - self.ctx.lookup_has_destructor( - item.id().expect_type_id(self.ctx), - ) - { - trace!( - " comp has destructor which cannot derive {}", - self.derive_trait - ); - return CanDerive::No; - } - - if info.kind() == CompKind::Union { - if self.derive_trait.can_derive_union() { - if self.ctx.options().rust_features().untagged_union && - // https://github.com/rust-lang/rust/issues/36640 - (!info.self_template_params(self.ctx).is_empty() || - !item.all_template_params(self.ctx).is_empty()) - { - trace!( - " cannot derive {} for Rust union because issue 36640", self.derive_trait - ); - return CanDerive::No; - } - // fall through to be same as non-union handling - } else { - if self.ctx.options().rust_features().untagged_union { - trace!( - " cannot derive {} for Rust unions", - self.derive_trait - ); - 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; - } - } - - if !self.derive_trait.can_derive_compound_with_vtable() && - item.has_vtable(self.ctx) - { - trace!( - " cannot derive {} for comp with vtable", - self.derive_trait - ); - return CanDerive::No; - } - - // Bitfield units are always represented as arrays of u8, but - // they're not traced as arrays, so we need to check here - // instead. - if !self.derive_trait.can_derive_large_array(self.ctx) && - info.has_too_large_bitfield_unit() && - !item.is_opaque(self.ctx, &()) - { - trace!( - " cannot derive {} for comp with too large bitfield unit", - self.derive_trait - ); - return CanDerive::No; - } - - let pred = self.derive_trait.consider_edge_comp(); - self.constrain_join(item, pred) - } - - TypeKind::ResolvedTypeRef(..) | - TypeKind::TemplateAlias(..) | - TypeKind::Alias(..) | - TypeKind::BlockPointer(..) => { - let pred = self.derive_trait.consider_edge_typeref(); - self.constrain_join(item, pred) - } - - TypeKind::TemplateInstantiation(..) => { - let pred = self.derive_trait.consider_edge_tmpl_inst(); - self.constrain_join(item, pred) - } - - TypeKind::Opaque => unreachable!( - "The early ty.is_opaque check should have handled this case" - ), - } - } - - fn constrain_join( - &mut self, - item: &Item, - consider_edge: EdgePredicate, - ) -> CanDerive { - let mut candidate = None; - - item.trace( - self.ctx, - &mut |sub_id, edge_kind| { - // Ignore ourselves, since union with ourself is a - // no-op. Ignore edges that aren't relevant to the - // analysis. - if sub_id == item.id() || !consider_edge(edge_kind) { - return; - } - - let can_derive = self.can_derive - .get(&sub_id) - .cloned() - .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), - } - - *candidate.get_or_insert(CanDerive::Yes) |= can_derive; - }, - &(), - ); - - if candidate.is_none() { - trace!( - " can derive {} because there are no members", - self.derive_trait - ); - } - candidate.unwrap_or_default() - } -} - -impl DeriveTrait { - 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), - DeriveTrait::Default => ctx.no_default_by_name(item), - DeriveTrait::Hash => ctx.no_hash_by_name(item), - DeriveTrait::PartialEqOrPartialOrd => { - ctx.no_partialeq_by_name(item) - } - } - } - - 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 { - match self { - DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, - _ => |kind| kind == EdgeKind::TypeReference, - } - } - - fn consider_edge_tmpl_inst(&self) -> EdgePredicate { - match self { - DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, - _ => |kind| match kind { - EdgeKind::TemplateArgument | EdgeKind::TemplateDeclaration => { - true - } - _ => false, - }, - } - } - - 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_union(&self) -> bool { - matches!(self, DeriveTrait::Copy) - } - - fn can_derive_compound_with_destructor(&self) -> bool { - !matches!(self, DeriveTrait::Copy) - } - - fn can_derive_compound_with_vtable(&self) -> bool { - !matches!(self, DeriveTrait::Default) - } - - fn can_derive_compound_forward_decl(&self) -> bool { - matches!(self, DeriveTrait::Copy | DeriveTrait::Debug) - } - - fn can_derive_incomplete_array(&self) -> bool { - !matches!( - self, - DeriveTrait::Copy | - DeriveTrait::Hash | - DeriveTrait::PartialEqOrPartialOrd - ) - } - - 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); - CanDerive::Yes - } - (DeriveTrait::Debug, false) => { - trace!(" function pointer cannot derive {}, but it may be implemented", self); - CanDerive::Manually - } - (_, false) => { - 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_pointer(&self) -> CanDerive { - match self { - DeriveTrait::Default => { - trace!(" pointer cannot derive Default"); - CanDerive::No - } - _ => { - trace!(" pointer can derive {}", self); - CanDerive::Yes - } - } - } - - 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) => { - trace!(" types that always cannot derive Default"); - CanDerive::No - } - (DeriveTrait::Default, TypeKind::UnresolvedTypeRef(..)) => { - unreachable!( - "Type with unresolved type ref can't reach derive default" - ) - } - // === Hash === - (DeriveTrait::Hash, TypeKind::Float(..)) | - (DeriveTrait::Hash, TypeKind::Complex(..)) => { - trace!(" float cannot derive Hash"); - CanDerive::No - } - // === others === - _ => { - trace!(" simple type that can always derive {}", self); - CanDerive::Yes - } - } - } -} - -impl fmt::Display for DeriveTrait { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let s = match self { - DeriveTrait::Copy => "Copy", - DeriveTrait::Debug => "Debug", - DeriveTrait::Default => "Default", - DeriveTrait::Hash => "Hash", - DeriveTrait::PartialEqOrPartialOrd => "PartialEq/PartialOrd", - }; - s.fmt(f) - } -} - -impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { - type Node = ItemId; - type Extra = (&'ctx BindgenContext, DeriveTrait); - type Output = HashMap; - - fn new( - (ctx, derive_trait): (&'ctx BindgenContext, DeriveTrait), - ) -> CannotDerive<'ctx> { - let can_derive = HashMap::default(); - let dependencies = generate_dependencies(ctx, consider_edge_default); - - CannotDerive { - ctx, - derive_trait, - can_derive, - dependencies, - } - } - - fn initial_worklist(&self) -> Vec { - // The transitive closure of all allowlisted items, including explicitly - // blocklisted items. - self.ctx - .allowlisted_items() - .iter() - .cloned() - .flat_map(|i| { - let mut reachable = vec![i]; - i.trace( - self.ctx, - &mut |s, _| { - reachable.push(s); - }, - &(), - ); - reachable - }) - .collect() - } - - fn constrain(&mut self, id: ItemId) -> ConstrainResult { - trace!("constrain: {:?}", id); - - if let Some(CanDerive::No) = self.can_derive.get(&id).cloned() { - trace!(" already know it cannot derive {}", self.derive_trait); - return ConstrainResult::Same; - } - - let item = self.ctx.resolve_item(id); - let can_derive = match item.as_type() { - Some(ty) => { - let mut can_derive = self.constrain_type(item, ty); - if let CanDerive::Yes = can_derive { - 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) - { - // We have to be conservative: the struct *could* have enough - // padding that we emit an array that is longer than - // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations - // into the IR and computed them before this analysis, then we could - // be precise rather than conservative here. - can_derive = CanDerive::Manually; - } - } - can_derive - } - None => self.constrain_join(item, consider_edge_default), - }; - - self.insert(id, can_derive) - } - - fn each_depending_on(&self, id: ItemId, mut f: F) - where - F: FnMut(ItemId), - { - if let Some(edges) = self.dependencies.get(&id) { - for item in edges { - trace!("enqueue {:?} into worklist", item); - f(*item); - } - } - } -} - -impl<'ctx> From> for HashMap { - fn from(analysis: CannotDerive<'ctx>) -> Self { - extra_assert!(analysis - .can_derive - .values() - .all(|v| *v != CanDerive::Yes)); - - analysis.can_derive - } -} - -/// Convert a `HashMap` into a `HashSet`. -/// -/// Elements that are not `CanDerive::Yes` are kept in the set, so that it -/// represents all items that cannot derive. -pub fn as_cannot_derive_set( - can_derive: HashMap, -) -> HashSet { - can_derive - .into_iter() - .filter_map(|(k, v)| if v != CanDerive::Yes { Some(k) } else { None }) - .collect() -} diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs deleted file mode 100644 index 40dfc6d644..0000000000 --- a/src/ir/analysis/mod.rs +++ /dev/null @@ -1,402 +0,0 @@ -//! Fix-point analyses on the IR using the "monotone framework". -//! -//! A lattice is a set with a partial ordering between elements, where there is -//! a single least upper bound and a single greatest least bound for every -//! subset. We are dealing with finite lattices, which means that it has a -//! finite number of elements, and it follows that there exists a single top and -//! a single bottom member of the lattice. For example, the power set of a -//! finite set forms a finite lattice where partial ordering is defined by set -//! inclusion, that is `a <= b` if `a` is a subset of `b`. Here is the finite -//! lattice constructed from the set {0,1,2}: -//! -//! ```text -//! .----- Top = {0,1,2} -----. -//! / | \ -//! / | \ -//! / | \ -//! {0,1} -------. {0,2} .--------- {1,2} -//! | \ / \ / | -//! | / \ | -//! | / \ / \ | -//! {0} --------' {1} `---------- {2} -//! \ | / -//! \ | / -//! \ | / -//! `------ Bottom = {} ------' -//! ``` -//! -//! A monotone function `f` is a function where if `x <= y`, then it holds that -//! `f(x) <= f(y)`. It should be clear that running a monotone function to a -//! fix-point on a finite lattice will always terminate: `f` can only "move" -//! along the lattice in a single direction, and therefore can only either find -//! a fix-point in the middle of the lattice or continue to the top or bottom -//! depending if it is ascending or descending the lattice respectively. -//! -//! For a deeper introduction to the general form of this kind of analysis, see -//! [Static Program Analysis by Anders Møller and Michael I. Schwartzbach][spa]. -//! -//! [spa]: https://cs.au.dk/~amoeller/spa/spa.pdf - -// Re-export individual analyses. -mod template_params; -pub use self::template_params::UsedTemplateParameters; -mod derive; -pub use self::derive::{as_cannot_derive_set, CannotDerive, DeriveTrait}; -mod has_vtable; -pub use self::has_vtable::{HasVtable, HasVtableAnalysis, HasVtableResult}; -mod has_destructor; -pub use self::has_destructor::HasDestructorAnalysis; -mod has_type_param_in_array; -pub use self::has_type_param_in_array::HasTypeParameterInArray; -mod has_float; -pub use self::has_float::HasFloat; -mod sizedness; -pub use self::sizedness::{Sizedness, SizednessAnalysis, SizednessResult}; - -use crate::ir::context::{BindgenContext, ItemId}; - -use crate::ir::traversal::{EdgeKind, Trace}; -use crate::HashMap; -use std::fmt; -use std::ops; - -/// An analysis in the monotone framework. -/// -/// Implementors of this trait must maintain the following two invariants: -/// -/// 1. The concrete data must be a member of a finite-height lattice. -/// 2. The concrete `constrain` method must be monotone: that is, -/// if `x <= y`, then `constrain(x) <= constrain(y)`. -/// -/// If these invariants do not hold, iteration to a fix-point might never -/// complete. -/// -/// For a simple example analysis, see the `ReachableFrom` type in the `tests` -/// module below. -pub trait MonotoneFramework: Sized + fmt::Debug { - /// The type of node in our dependency graph. - /// - /// This is just generic (and not `ItemId`) so that we can easily unit test - /// without constructing real `Item`s and their `ItemId`s. - type Node: Copy; - - /// Any extra data that is needed during computation. - /// - /// Again, this is just generic (and not `&BindgenContext`) so that we can - /// easily unit test without constructing real `BindgenContext`s full of - /// real `Item`s and real `ItemId`s. - type Extra: Sized; - - /// The final output of this analysis. Once we have reached a fix-point, we - /// convert `self` into this type, and return it as the final result of the - /// analysis. - type Output: From + fmt::Debug; - - /// Construct a new instance of this analysis. - fn new(extra: Self::Extra) -> Self; - - /// Get the initial set of nodes from which to start the analysis. Unless - /// you are sure of some domain-specific knowledge, this should be the - /// complete set of nodes. - fn initial_worklist(&self) -> Vec; - - /// Update the analysis for the given node. - /// - /// If this results in changing our internal state (ie, we discovered that - /// we have not reached a fix-point and iteration should continue), return - /// `ConstrainResult::Changed`. Otherwise, return `ConstrainResult::Same`. - /// When `constrain` returns `ConstrainResult::Same` for all nodes in the - /// set, we have reached a fix-point and the analysis is complete. - fn constrain(&mut self, node: Self::Node) -> ConstrainResult; - - /// For each node `d` that depends on the given `node`'s current answer when - /// running `constrain(d)`, call `f(d)`. This informs us which new nodes to - /// queue up in the worklist when `constrain(node)` reports updated - /// information. - fn each_depending_on(&self, node: Self::Node, f: F) - where - F: FnMut(Self::Node); -} - -/// Whether an analysis's `constrain` function modified the incremental results -/// or not. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum ConstrainResult { - /// The incremental results were updated, and the fix-point computation - /// should continue. - Changed, - - /// The incremental results were not updated. - Same, -} - -impl Default for ConstrainResult { - fn default() -> Self { - ConstrainResult::Same - } -} - -impl ops::BitOr for ConstrainResult { - type Output = Self; - - fn bitor(self, rhs: ConstrainResult) -> Self::Output { - if self == ConstrainResult::Changed || rhs == ConstrainResult::Changed { - ConstrainResult::Changed - } else { - ConstrainResult::Same - } - } -} - -impl ops::BitOrAssign for ConstrainResult { - fn bitor_assign(&mut self, rhs: ConstrainResult) { - *self = *self | rhs; - } -} - -/// Run an analysis in the monotone framework. -pub fn analyze(extra: Analysis::Extra) -> Analysis::Output -where - Analysis: MonotoneFramework, -{ - let mut analysis = Analysis::new(extra); - let mut worklist = analysis.initial_worklist(); - - while let Some(node) = worklist.pop() { - if let ConstrainResult::Changed = analysis.constrain(node) { - analysis.each_depending_on(node, |needs_work| { - worklist.push(needs_work); - }); - } - } - - analysis.into() -} - -/// Generate the dependency map for analysis -pub fn generate_dependencies( - ctx: &BindgenContext, - consider_edge: F, -) -> HashMap> -where - F: Fn(EdgeKind) -> bool, -{ - let mut dependencies = HashMap::default(); - - for &item in ctx.allowlisted_items() { - dependencies.entry(item).or_insert_with(Vec::new); - - { - // We reverse our natural IR graph edges to find dependencies - // between nodes. - item.trace( - ctx, - &mut |sub_item: ItemId, edge_kind| { - if ctx.allowlisted_items().contains(&sub_item) && - consider_edge(edge_kind) - { - dependencies - .entry(sub_item) - .or_insert_with(Vec::new) - .push(item); - } - }, - &(), - ); - } - } - dependencies -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{HashMap, HashSet}; - - // Here we find the set of nodes that are reachable from any given - // node. This is a lattice mapping nodes to subsets of all nodes. Our join - // function is set union. - // - // This is our test graph: - // - // +---+ +---+ - // | | | | - // | 1 | .----| 2 | - // | | | | | - // +---+ | +---+ - // | | ^ - // | | | - // | +---+ '------' - // '----->| | - // | 3 | - // .------| |------. - // | +---+ | - // | ^ | - // v | v - // +---+ | +---+ +---+ - // | | | | | | | - // | 4 | | | 5 |--->| 6 | - // | | | | | | | - // +---+ | +---+ +---+ - // | | | | - // | | | v - // | +---+ | +---+ - // | | | | | | - // '----->| 7 |<-----' | 8 | - // | | | | - // +---+ +---+ - // - // And here is the mapping from a node to the set of nodes that are - // reachable from it within the test graph: - // - // 1: {3,4,5,6,7,8} - // 2: {2} - // 3: {3,4,5,6,7,8} - // 4: {3,4,5,6,7,8} - // 5: {3,4,5,6,7,8} - // 6: {8} - // 7: {3,4,5,6,7,8} - // 8: {} - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] - struct Node(usize); - - #[derive(Clone, Debug, Default, PartialEq, Eq)] - struct Graph(HashMap>); - - impl Graph { - fn make_test_graph() -> Graph { - let mut g = Graph::default(); - g.0.insert(Node(1), vec![Node(3)]); - g.0.insert(Node(2), vec![Node(2)]); - g.0.insert(Node(3), vec![Node(4), Node(5)]); - g.0.insert(Node(4), vec![Node(7)]); - g.0.insert(Node(5), vec![Node(6), Node(7)]); - g.0.insert(Node(6), vec![Node(8)]); - g.0.insert(Node(7), vec![Node(3)]); - g.0.insert(Node(8), vec![]); - g - } - - fn reverse(&self) -> Graph { - let mut reversed = Graph::default(); - for (node, edges) in self.0.iter() { - reversed.0.entry(*node).or_insert_with(Vec::new); - for referent in edges.iter() { - reversed - .0 - .entry(*referent) - .or_insert_with(Vec::new) - .push(*node); - } - } - reversed - } - } - - #[derive(Clone, Debug, PartialEq, Eq)] - struct ReachableFrom<'a> { - reachable: HashMap>, - graph: &'a Graph, - reversed: Graph, - } - - impl<'a> MonotoneFramework for ReachableFrom<'a> { - type Node = Node; - type Extra = &'a Graph; - type Output = HashMap>; - - fn new(graph: &'a Graph) -> ReachableFrom { - let reversed = graph.reverse(); - ReachableFrom { - reachable: Default::default(), - graph, - reversed, - } - } - - fn initial_worklist(&self) -> Vec { - self.graph.0.keys().cloned().collect() - } - - fn constrain(&mut self, node: Node) -> ConstrainResult { - // The set of nodes reachable from a node `x` is - // - // reachable(x) = s_0 U s_1 U ... U reachable(s_0) U reachable(s_1) U ... - // - // where there exist edges from `x` to each of `s_0, s_1, ...`. - // - // Yes, what follows is a **terribly** inefficient set union - // implementation. Don't copy this code outside of this test! - - let original_size = self - .reachable - .entry(node) - .or_insert_with(HashSet::default) - .len(); - - for sub_node in self.graph.0[&node].iter() { - self.reachable.get_mut(&node).unwrap().insert(*sub_node); - - let sub_reachable = self - .reachable - .entry(*sub_node) - .or_insert_with(HashSet::default) - .clone(); - - for transitive in sub_reachable { - self.reachable.get_mut(&node).unwrap().insert(transitive); - } - } - - let new_size = self.reachable[&node].len(); - if original_size != new_size { - ConstrainResult::Changed - } else { - ConstrainResult::Same - } - } - - fn each_depending_on(&self, node: Node, mut f: F) - where - F: FnMut(Node), - { - for dep in self.reversed.0[&node].iter() { - f(*dep); - } - } - } - - impl<'a> From> for HashMap> { - fn from(reachable: ReachableFrom<'a>) -> Self { - reachable.reachable - } - } - - #[test] - fn monotone() { - let g = Graph::make_test_graph(); - let reachable = analyze::(&g); - println!("reachable = {:#?}", reachable); - - fn nodes(nodes: A) -> HashSet - where - A: AsRef<[usize]>, - { - nodes.as_ref().iter().cloned().map(Node).collect() - } - - let mut expected = HashMap::default(); - expected.insert(Node(1), nodes([3, 4, 5, 6, 7, 8])); - expected.insert(Node(2), nodes([2])); - expected.insert(Node(3), nodes([3, 4, 5, 6, 7, 8])); - expected.insert(Node(4), nodes([3, 4, 5, 6, 7, 8])); - expected.insert(Node(5), nodes([3, 4, 5, 6, 7, 8])); - 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); - - assert_eq!(reachable, expected); - } -} diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs deleted file mode 100644 index 9bcda508ee..0000000000 --- a/src/ir/annotations.rs +++ /dev/null @@ -1,211 +0,0 @@ -//! Types and functions related to bindgen annotation comments. -//! -//! Users can add annotations in doc comments to types that they would like to -//! replace other types with, mark as opaque, etc. This module deals with all of -//! that stuff. - -use crate::clang; - -/// What kind of accessor should we provide for a field? -#[derive(Copy, PartialEq, Clone, Debug)] -pub enum FieldAccessorKind { - /// No accessor. - None, - /// Plain accessor. - Regular, - /// Unsafe accessor. - Unsafe, - /// Immutable accessor. - Immutable, -} - -/// Annotations for a given item, or a field. -/// -/// You can see the kind of comments that are accepted in the Doxygen -/// documentation: -/// -/// http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html -#[derive(Default, Clone, PartialEq, Debug)] -pub struct Annotations { - /// Whether this item is marked as opaque. Only applies to types. - opaque: bool, - /// Whether this item should be hidden from the output. Only applies to - /// types, or enum variants. - hide: bool, - /// Whether this type should be replaced by another. The name is a - /// namespace-aware path. - use_instead_of: Option>, - /// Manually disable deriving copy/clone on this type. Only applies to - /// struct or union types. - disallow_copy: bool, - /// Manually disable deriving debug on this type. - disallow_debug: bool, - /// Manually disable deriving/implement default on this type. - disallow_default: bool, - /// Whether to add a #[must_use] annotation to this type. - must_use_type: bool, - /// Whether fields should be marked as private or not. You can set this on - /// structs (it will apply to all the fields), or individual fields. - private_fields: Option, - /// The kind of accessor this field will have. Also can be applied to - /// structs so all the fields inside share it by default. - accessor_kind: Option, - /// Whether this enum variant should be constified. - /// - /// This is controlled by the `constant` attribute, this way: - /// - /// ```cpp - /// enum Foo { - /// Bar = 0, /**<

*/ - /// Baz = 0, - /// }; - /// ``` - /// - /// In that case, bindgen will generate a constant for `Bar` instead of - /// `Baz`. - constify_enum_variant: bool, - /// List of explicit derives for this type. - derives: Vec, -} - -fn parse_accessor(s: &str) -> FieldAccessorKind { - match s { - "false" => FieldAccessorKind::None, - "unsafe" => FieldAccessorKind::Unsafe, - "immutable" => FieldAccessorKind::Immutable, - _ => FieldAccessorKind::Regular, - } -} - -impl Annotations { - /// Construct new annotations for the given cursor and its bindgen comments - /// (if any). - pub fn new(cursor: &clang::Cursor) -> Option { - let mut anno = Annotations::default(); - let mut matched_one = false; - anno.parse(&cursor.comment(), &mut matched_one); - - if matched_one { - Some(anno) - } else { - None - } - } - - /// Should this type be hidden? - pub fn hide(&self) -> bool { - self.hide - } - - /// Should this type be opaque? - pub fn opaque(&self) -> bool { - self.opaque - } - - /// For a given type, indicates the type it should replace. - /// - /// For example, in the following code: - /// - /// ```cpp - /// - /// /**
*/ - /// struct Foo { int x; }; - /// - /// struct Bar { char foo; }; - /// ``` - /// - /// the generated code would look something like: - /// - /// ``` - /// /**
*/ - /// struct Bar { - /// x: ::std::os::raw::c_int, - /// }; - /// ``` - /// - /// That is, code for `Foo` is used to generate `Bar`. - pub fn use_instead_of(&self) -> Option<&[String]> { - self.use_instead_of.as_deref() - } - - /// The list of derives that have been specified in this annotation. - pub fn derives(&self) -> &[String] { - &self.derives - } - - /// Should we avoid implementing the `Copy` trait? - pub fn disallow_copy(&self) -> bool { - self.disallow_copy - } - - /// Should we avoid implementing the `Debug` trait? - pub fn disallow_debug(&self) -> bool { - self.disallow_debug - } - - /// Should we avoid implementing the `Default` trait? - pub fn disallow_default(&self) -> bool { - self.disallow_default - } - - /// Should this type get a `#[must_use]` annotation? - pub fn must_use_type(&self) -> bool { - self.must_use_type - } - - /// Should the fields be private? - pub fn private_fields(&self) -> Option { - self.private_fields - } - - /// What kind of accessors should we provide for this type's fields? - pub fn accessor_kind(&self) -> Option { - self.accessor_kind - } - - fn parse(&mut self, comment: &clang::Comment, matched: &mut bool) { - use clang_sys::CXComment_HTMLStartTag; - if comment.kind() == CXComment_HTMLStartTag && - comment.get_tag_name() == "div" && - comment - .get_tag_attrs() - .next() - .map_or(false, |attr| attr.name == "rustbindgen") - { - *matched = true; - for attr in comment.get_tag_attrs() { - match attr.name.as_str() { - "opaque" => self.opaque = true, - "hide" => self.hide = true, - "nocopy" => self.disallow_copy = true, - "nodebug" => self.disallow_debug = true, - "nodefault" => self.disallow_default = true, - "mustusetype" => self.must_use_type = true, - "replaces" => { - self.use_instead_of = Some( - attr.value.split("::").map(Into::into).collect(), - ) - } - "derive" => self.derives.push(attr.value), - "private" => { - self.private_fields = Some(attr.value != "false") - } - "accessor" => { - self.accessor_kind = Some(parse_accessor(&attr.value)) - } - "constant" => self.constify_enum_variant = true, - _ => {} - } - } - } - - for child in comment.get_children() { - self.parse(&child, matched); - } - } - - /// Returns whether we've parsed a "constant" attribute. - pub fn constify_enum_variant(&self) -> bool { - self.constify_enum_variant - } -} diff --git a/src/ir/comment.rs b/src/ir/comment.rs deleted file mode 100644 index c96e3ebb9e..0000000000 --- a/src/ir/comment.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! Utilities for manipulating C/C++ comments. - -/// The type of a comment. -#[derive(Debug, PartialEq, Eq)] -enum Kind { - /// A `///` comment, or something of the like. - /// All lines in a comment should start with the same symbol. - SingleLines, - /// A `/**` comment, where each other line can start with `*` and the - /// entire block ends with `*/`. - MultiLine, -} - -/// Preprocesses a C/C++ comment so that it is a valid Rust comment. -pub fn preprocess(comment: &str, indent: usize) -> String { - match self::kind(comment) { - Some(Kind::SingleLines) => preprocess_single_lines(comment, indent), - Some(Kind::MultiLine) => preprocess_multi_line(comment, indent), - None => comment.to_owned(), - } -} - -/// Gets the kind of the doc comment, if it is one. -fn kind(comment: &str) -> Option { - if comment.starts_with("/*") { - Some(Kind::MultiLine) - } else if comment.starts_with("//") { - Some(Kind::SingleLines) - } else { - None - } -} - -fn make_indent(indent: usize) -> String { - const RUST_INDENTATION: usize = 4; - " ".repeat(indent * RUST_INDENTATION) -} - -/// Preprocesses multiple single line comments. -/// -/// Handles lines starting with both `//` and `///`. -fn preprocess_single_lines(comment: &str, indent: usize) -> String { - debug_assert!(comment.starts_with("//"), "comment is not single line"); - - let indent = make_indent(indent); - let mut is_first = true; - let lines: Vec<_> = comment - .lines() - .map(|l| l.trim().trim_start_matches('/')) - .map(|l| { - let indent = if is_first { "" } else { &*indent }; - is_first = false; - format!("{}///{}", indent, l) - }) - .collect(); - lines.join("\n") -} - -fn preprocess_multi_line(comment: &str, indent: usize) -> String { - let comment = comment - .trim_start_matches('/') - .trim_end_matches('/') - .trim_end_matches('*'); - - let indent = make_indent(indent); - // Strip any potential `*` characters preceding each line. - let mut is_first = true; - let mut lines: Vec<_> = comment - .lines() - .map(|line| line.trim().trim_start_matches('*').trim_start_matches('!')) - .skip_while(|line| line.trim().is_empty()) // Skip the first empty lines. - .map(|line| { - let indent = if is_first { "" } else { &*indent }; - is_first = false; - format!("{}///{}", indent, line) - }) - .collect(); - - // Remove the trailing line corresponding to the `*/`. - if lines - .last() - .map_or(false, |l| l.trim().is_empty() || l.trim() == "///") - { - lines.pop(); - } - - lines.join("\n") -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn picks_up_single_and_multi_line_doc_comments() { - assert_eq!(kind("/// hello"), Some(Kind::SingleLines)); - assert_eq!(kind("/** world */"), Some(Kind::MultiLine)); - } - - #[test] - fn processes_single_lines_correctly() { - assert_eq!(preprocess("/// hello", 0), "/// hello"); - assert_eq!(preprocess("// hello", 0), "/// hello"); - assert_eq!(preprocess("// hello", 0), "/// hello"); - } - - #[test] - fn processes_multi_lines_correctly() { - assert_eq!( - preprocess("/** hello \n * world \n * foo \n */", 0), - "/// hello\n/// world\n/// foo" - ); - - assert_eq!( - preprocess("/**\nhello\n*world\n*foo\n*/", 0), - "///hello\n///world\n///foo" - ); - } -} diff --git a/src/ir/derive.rs b/src/ir/derive.rs deleted file mode 100644 index 594ce2ab8f..0000000000 --- a/src/ir/derive.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! Traits for determining whether we can derive traits for a thing or not. -//! -//! These traits tend to come in pairs: -//! -//! 1. A "trivial" version, whose implementations aren't allowed to recursively -//! look at other types or the results of fix point analyses. -//! -//! 2. A "normal" version, whose implementations simply query the results of a -//! fix point analysis. -//! -//! The former is used by the analyses when creating the results queried by the -//! second. - -use super::context::BindgenContext; - -use std::cmp; -use std::ops; - -/// A trait that encapsulates the logic for whether or not we can derive `Debug` -/// for a given thing. -pub trait CanDeriveDebug { - /// Return `true` if `Debug` can be derived for this thing, `false` - /// otherwise. - fn can_derive_debug(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive `Copy` -/// for a given thing. -pub trait CanDeriveCopy { - /// Return `true` if `Copy` can be derived for this thing, `false` - /// otherwise. - fn can_derive_copy(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive -/// `Default` for a given thing. -pub trait CanDeriveDefault { - /// Return `true` if `Default` can be derived for this thing, `false` - /// otherwise. - fn can_derive_default(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive `Hash` -/// for a given thing. -pub trait CanDeriveHash { - /// Return `true` if `Hash` can be derived for this thing, `false` - /// otherwise. - fn can_derive_hash(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive -/// `PartialEq` for a given thing. -pub trait CanDerivePartialEq { - /// Return `true` if `PartialEq` can be derived for this thing, `false` - /// otherwise. - fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive -/// `PartialOrd` for a given thing. -pub trait CanDerivePartialOrd { - /// Return `true` if `PartialOrd` can be derived for this thing, `false` - /// otherwise. - fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive `Eq` -/// for a given thing. -pub trait CanDeriveEq { - /// Return `true` if `Eq` can be derived for this thing, `false` otherwise. - fn can_derive_eq(&self, ctx: &BindgenContext) -> bool; -} - -/// A trait that encapsulates the logic for whether or not we can derive `Ord` -/// for a given thing. -pub trait CanDeriveOrd { - /// Return `true` if `Ord` can be derived for this thing, `false` otherwise. - fn can_derive_ord(&self, ctx: &BindgenContext) -> bool; -} - -/// Whether it is possible or not to automatically derive trait for an item. -/// -/// ```ignore -/// No -/// ^ -/// | -/// Manually -/// ^ -/// | -/// Yes -/// ``` -/// -/// Initially we assume that we can derive trait for all types and then -/// update our understanding as we learn more about each type. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum CanDerive { - /// Yes, we can derive automatically. - Yes, - - /// The only thing that stops us from automatically deriving is that - /// array with more than maximum number of elements is used. - /// - /// This means we probably can "manually" implement such trait. - Manually, - - /// No, we cannot. - No, -} - -impl Default for CanDerive { - fn default() -> CanDerive { - CanDerive::Yes - } -} - -impl CanDerive { - /// Take the least upper bound of `self` and `rhs`. - pub fn join(self, rhs: Self) -> Self { - cmp::max(self, rhs) - } -} - -impl ops::BitOr for CanDerive { - type Output = Self; - - fn bitor(self, rhs: Self) -> Self::Output { - self.join(rhs) - } -} - -impl ops::BitOrAssign for CanDerive { - fn bitor_assign(&mut self, rhs: Self) { - *self = self.join(rhs) - } -} diff --git a/src/ir/function.rs b/src/ir/function.rs deleted file mode 100644 index 0ba2d1ee51..0000000000 --- a/src/ir/function.rs +++ /dev/null @@ -1,657 +0,0 @@ -//! Intermediate representation for C/C++ functions and methods. - -use super::comp::MethodKind; -use super::context::{BindgenContext, TypeId}; -use super::dot::DotAttributes; -use super::item::Item; -use super::traversal::{EdgeKind, Trace, Tracer}; -use super::ty::TypeKind; -use crate::clang; -use crate::parse::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; -use clang_sys::{self, CXCallingConv}; -use proc_macro2; -use quote; -use quote::TokenStreamExt; -use std::io; - -const RUST_DERIVE_FUNPTR_LIMIT: usize = 12; - -/// What kind of a function are we looking at? -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum FunctionKind { - /// A plain, free function. - Function, - /// A method of some kind. - Method(MethodKind), -} - -impl FunctionKind { - /// Given a clang cursor, return the kind of function it represents, or - /// `None` otherwise. - pub fn from_cursor(cursor: &clang::Cursor) -> Option { - // FIXME(emilio): Deduplicate logic with `ir::comp`. - Some(match cursor.kind() { - clang_sys::CXCursor_FunctionDecl => FunctionKind::Function, - clang_sys::CXCursor_Constructor => { - FunctionKind::Method(MethodKind::Constructor) - } - clang_sys::CXCursor_Destructor => { - FunctionKind::Method(if cursor.method_is_virtual() { - MethodKind::VirtualDestructor { - pure_virtual: cursor.method_is_pure_virtual(), - } - } else { - MethodKind::Destructor - }) - } - clang_sys::CXCursor_CXXMethod => { - if cursor.method_is_virtual() { - FunctionKind::Method(MethodKind::Virtual { - pure_virtual: cursor.method_is_pure_virtual(), - }) - } else if cursor.method_is_static() { - FunctionKind::Method(MethodKind::Static) - } else { - FunctionKind::Method(MethodKind::Normal) - } - } - _ => return None, - }) - } -} - -/// The style of linkage -#[derive(Debug, Clone, Copy)] -pub enum Linkage { - /// Externally visible and can be linked against - External, - /// Not exposed externally. 'static inline' functions will have this kind of linkage - Internal, -} - -/// A function declaration, with a signature, arguments, and argument names. -/// -/// The argument names vector must be the same length as the ones in the -/// signature. -#[derive(Debug)] -pub struct Function { - /// The name of this function. - name: String, - - /// The mangled name, that is, the symbol. - mangled_name: Option, - - /// The id pointing to the current function signature. - signature: TypeId, - - /// The doc comment on the function, if any. - comment: Option, - - /// The kind of function this is. - kind: FunctionKind, - - /// The linkage of the function. - linkage: Linkage, -} - -impl Function { - /// Construct a new function. - pub fn new( - name: String, - mangled_name: Option, - signature: TypeId, - comment: Option, - kind: FunctionKind, - linkage: Linkage, - ) -> Self { - Function { - name, - mangled_name, - signature, - comment, - kind, - linkage, - } - } - - /// Get this function's name. - pub fn name(&self) -> &str { - &self.name - } - - /// Get this function's name. - pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_deref() - } - - /// Get this function's signature type. - pub fn signature(&self) -> TypeId { - self.signature - } - - /// Get this function's comment. - pub fn comment(&self) -> Option<&str> { - self.comment.as_deref() - } - - /// Get this function's kind. - pub fn kind(&self) -> FunctionKind { - self.kind - } - - /// Get this function's linkage. - pub fn linkage(&self) -> Linkage { - self.linkage - } -} - -impl DotAttributes for Function { - fn dot_attributes( - &self, - _ctx: &BindgenContext, - out: &mut W, - ) -> io::Result<()> - where - W: io::Write, - { - 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 - )?; - } - - Ok(()) - } -} - -/// An ABI extracted from a clang cursor. -#[derive(Debug, Copy, Clone)] -pub enum Abi { - /// The default C ABI. - C, - /// The "stdcall" ABI. - Stdcall, - /// The "fastcall" ABI. - Fastcall, - /// The "thiscall" ABI. - ThisCall, - /// The "aapcs" ABI. - Aapcs, - /// The "win64" ABI. - Win64, - /// An unknown or invalid ABI. - Unknown(CXCallingConv), -} - -impl Abi { - /// Returns whether this Abi is known or not. - fn is_unknown(&self) -> bool { - matches!(*self, Abi::Unknown(..)) - } -} - -impl quote::ToTokens for Abi { - fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { - tokens.append_all(match *self { - Abi::C => quote! { "C" }, - Abi::Stdcall => quote! { "stdcall" }, - Abi::Fastcall => quote! { "fastcall" }, - Abi::ThisCall => quote! { "thiscall" }, - Abi::Aapcs => quote! { "aapcs" }, - Abi::Win64 => quote! { "win64" }, - Abi::Unknown(cc) => panic!( - "Cannot turn unknown calling convention to tokens: {:?}", - cc - ), - }); - } -} - -/// A function signature. -#[derive(Debug)] -pub struct FunctionSig { - /// The return type of the function. - return_type: TypeId, - - /// The type of the arguments, optionally with the name of the argument when - /// declared. - argument_types: Vec<(Option, TypeId)>, - - /// Whether this function is variadic. - is_variadic: bool, - - /// Whether this function's return value must be used. - must_use: bool, - - /// The ABI of this function. - abi: Abi, -} - -fn get_abi(cc: CXCallingConv) -> Abi { - use clang_sys::*; - match cc { - CXCallingConv_Default => Abi::C, - CXCallingConv_C => Abi::C, - CXCallingConv_X86StdCall => Abi::Stdcall, - CXCallingConv_X86FastCall => Abi::Fastcall, - CXCallingConv_X86ThisCall => Abi::ThisCall, - CXCallingConv_AAPCS => Abi::Aapcs, - CXCallingConv_X86_64Win64 => Abi::Win64, - other => Abi::Unknown(other), - } -} - -/// Get the mangled name for the cursor's referent. -pub fn cursor_mangling( - ctx: &BindgenContext, - cursor: &clang::Cursor, -) -> Option { - if !ctx.options().enable_mangling { - return None; - } - - // We early return here because libclang may crash in some case - // if we pass in a variable inside a partial specialized template. - // See rust-lang/rust-bindgen#67, and rust-lang/rust-bindgen#462. - if cursor.is_in_non_fully_specialized_template() { - return None; - } - - let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor; - if let Ok(mut manglings) = cursor.cxx_manglings() { - while let Some(m) = manglings.pop() { - // Only generate the destructor group 1, see below. - if is_destructor && !m.ends_with("D1Ev") { - continue; - } - - return Some(m); - } - } - - let mut mangling = cursor.mangling(); - if mangling.is_empty() { - return None; - } - - if is_destructor { - // With old (3.8-) libclang versions, and the Itanium ABI, clang returns - // the "destructor group 0" symbol, which means that it'll try to free - // memory, which definitely isn't what we want. - // - // Explicitly force the destructor group 1 symbol. - // - // See http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling-special - // for the reference, and http://stackoverflow.com/a/6614369/1091587 for - // a more friendly explanation. - // - // We don't need to do this for constructors since clang seems to always - // have returned the C1 constructor. - // - // FIXME(emilio): Can a legit symbol in other ABIs end with this string? - // I don't think so, but if it can this would become a linker error - // anyway, not an invalid free at runtime. - // - // TODO(emilio, #611): Use cpp_demangle if this becomes nastier with - // time. - if mangling.ends_with("D0Ev") { - let new_len = mangling.len() - 4; - mangling.truncate(new_len); - mangling.push_str("D1Ev"); - } - } - - Some(mangling) -} - -fn args_from_ty_and_cursor( - ty: &clang::Type, - cursor: &clang::Cursor, - ctx: &mut BindgenContext, -) -> Vec<(Option, TypeId)> { - let cursor_args = cursor.args().unwrap_or_default().into_iter(); - let type_args = ty.args().unwrap_or_default().into_iter(); - - // Argument types can be found in either the cursor or the type, but argument names may only be - // found on the cursor. We often have access to both a type and a cursor for each argument, but - // in some cases we may only have one. - // - // Prefer using the type as the source of truth for the argument's type, but fall back to - // inspecting the cursor (this happens for Objective C interfaces). - // - // Prefer using the cursor for the argument's type, but fall back to using the parent's cursor - // (this happens for function pointer return types). - cursor_args - .map(Some) - .chain(std::iter::repeat(None)) - .zip(type_args.map(Some).chain(std::iter::repeat(None))) - .take_while(|(cur, ty)| cur.is_some() || ty.is_some()) - .map(|(arg_cur, arg_ty)| { - let name = arg_cur.map(|a| a.spelling()).and_then(|name| { - if name.is_empty() { - None - } else { - Some(name) - } - }); - - let cursor = arg_cur.unwrap_or(*cursor); - let ty = arg_ty.unwrap_or_else(|| cursor.cur_type()); - (name, Item::from_ty_or_ref(ty, cursor, None, ctx)) - }) - .collect() -} - -impl FunctionSig { - /// Construct a new function signature. - pub fn new( - return_type: TypeId, - argument_types: Vec<(Option, TypeId)>, - is_variadic: bool, - must_use: bool, - abi: Abi, - ) -> Self { - FunctionSig { - return_type, - argument_types, - is_variadic, - must_use, - abi, - } - } - - /// Construct a new function signature from the given Clang type. - pub fn from_ty( - ty: &clang::Type, - cursor: &clang::Cursor, - ctx: &mut BindgenContext, - ) -> Result { - use clang_sys::*; - debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); - - // Skip function templates - let kind = cursor.kind(); - if kind == CXCursor_FunctionTemplate { - return Err(ParseError::Continue); - } - - let spelling = cursor.spelling(); - - // Don't parse operatorxx functions in C++ - let is_operator = |spelling: &str| { - spelling.starts_with("operator") && - !clang::is_valid_identifier(spelling) - }; - if is_operator(&spelling) { - return Err(ParseError::Continue); - } - - // Constructors of non-type template parameter classes for some reason - // include the template parameter in their name. Just skip them, since - // we don't handle well non-type template parameters anyway. - if (kind == CXCursor_Constructor || kind == CXCursor_Destructor) && - spelling.contains('<') - { - return Err(ParseError::Continue); - } - - let cursor = if cursor.is_valid() { - *cursor - } else { - ty.declaration() - }; - - let mut args = match kind { - CXCursor_FunctionDecl | - CXCursor_Constructor | - CXCursor_CXXMethod | - CXCursor_ObjCInstanceMethodDecl | - CXCursor_ObjCClassMethodDecl => { - args_from_ty_and_cursor(ty, &cursor, ctx) - } - _ => { - // For non-CXCursor_FunctionDecl, visiting the cursor's children - // is the only reliable way to get parameter names. - let mut args = vec![]; - cursor.visit(|c| { - if c.kind() == CXCursor_ParmDecl { - let ty = - Item::from_ty_or_ref(c.cur_type(), c, None, ctx); - let name = c.spelling(); - let name = - if name.is_empty() { None } else { Some(name) }; - args.push((name, ty)); - } - CXChildVisit_Continue - }); - - if args.is_empty() { - // FIXME(emilio): Sometimes libclang doesn't expose the - // right AST for functions tagged as stdcall and such... - // - // https://bugs.llvm.org/show_bug.cgi?id=45919 - args_from_ty_and_cursor(ty, &cursor, ctx) - } else { - args - } - } - }; - - let must_use = ctx.options().enable_function_attribute_detection && - cursor.has_warn_unused_result_attr(); - let is_method = kind == CXCursor_CXXMethod; - let is_constructor = kind == CXCursor_Constructor; - let is_destructor = kind == CXCursor_Destructor; - if (is_constructor || is_destructor || is_method) && - cursor.lexical_parent() != cursor.semantic_parent() - { - // Only parse constructors once. - return Err(ParseError::Continue); - } - - if is_method || is_constructor || is_destructor { - 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 { - let parent = cursor.semantic_parent(); - let class = Item::parse(parent, None, ctx) - .expect("Expected to parse the class"); - // The `class` most likely is not finished parsing yet, so use - // the unchecked variant. - let class = class.as_type_id_unchecked(); - - let class = if is_const { - let const_class_id = ctx.next_item_id(); - ctx.build_const_wrapper( - const_class_id, - class, - None, - &parent.cur_type(), - ) - } else { - class - }; - - let ptr = - Item::builtin_type(TypeKind::Pointer(class), false, ctx); - args.insert(0, (Some("this".into()), ptr)); - } else if is_virtual { - let void = Item::builtin_type(TypeKind::Void, false, ctx); - let ptr = - Item::builtin_type(TypeKind::Pointer(void), false, ctx); - args.insert(0, (Some("this".into()), ptr)); - } - } - - let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl || - kind == CXCursor_ObjCClassMethodDecl - { - ty.ret_type() - .or_else(|| cursor.ret_type()) - .ok_or(ParseError::Continue)? - } else { - ty.ret_type().ok_or(ParseError::Continue)? - }; - - let ret = if is_constructor && ctx.is_target_wasm32() { - // Constructors in Clang wasm32 target return a pointer to the object - // being constructed. - let void = Item::builtin_type(TypeKind::Void, false, ctx); - Item::builtin_type(TypeKind::Pointer(void), false, ctx) - } else { - Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx) - }; - - // Clang plays with us at "find the calling convention", see #549 and - // co. This seems to be a better fix than that commit. - let mut call_conv = ty.call_conv(); - if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() { - let cursor_call_conv = ty.call_conv(); - if cursor_call_conv != CXCallingConv_Invalid { - call_conv = cursor_call_conv; - } - } - let abi = get_abi(call_conv); - - if abi.is_unknown() { - warn!("Unknown calling convention: {:?}", call_conv); - } - - Ok(Self::new(ret, args, ty.is_variadic(), must_use, abi)) - } - - /// Get this function signature's return type. - pub fn return_type(&self) -> TypeId { - self.return_type - } - - /// Get this function signature's argument (name, type) pairs. - pub fn argument_types(&self) -> &[(Option, TypeId)] { - &self.argument_types - } - - /// Get this function signature's ABI. - pub fn abi(&self) -> Abi { - self.abi - } - - /// Is this function signature variadic? - pub fn is_variadic(&self) -> bool { - // Clang reports some functions as variadic when they *might* be - // variadic. We do the argument check because rust doesn't codegen well - // variadic functions without an initial argument. - self.is_variadic && !self.argument_types.is_empty() - } - - /// Must this function's return value be used? - pub fn must_use(&self) -> bool { - self.must_use - } - - /// Are function pointers with this signature able to derive Rust traits? - /// Rust only supports deriving traits for function pointers with a limited - /// number of parameters and a couple ABIs. - /// - /// For more details, see: - /// - /// * https://github.com/rust-lang/rust-bindgen/issues/547, - /// * https://github.com/rust-lang/rust/issues/38848, - /// * and https://github.com/rust-lang/rust/issues/40158 - pub fn function_pointers_can_derive(&self) -> bool { - if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT { - return false; - } - - matches!(self.abi, Abi::C | Abi::Unknown(..)) - } -} - -impl ClangSubItemParser for Function { - fn parse( - cursor: clang::Cursor, - context: &mut BindgenContext, - ) -> Result, ParseError> { - use clang_sys::*; - - let kind = match FunctionKind::from_cursor(&cursor) { - None => return Err(ParseError::Continue), - Some(k) => k, - }; - - 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 { - return Err(ParseError::Continue); - } - - if cursor.is_inlined_function() { - if !context.options().generate_inline_functions { - return Err(ParseError::Continue); - } - if cursor.is_deleted_function() { - return Err(ParseError::Continue); - } - } - - let linkage = cursor.linkage(); - let linkage = match linkage { - CXLinkage_External | CXLinkage_UniqueExternal => Linkage::External, - CXLinkage_Internal => Linkage::Internal, - _ => return Err(ParseError::Continue), - }; - - // Grab the signature using Item::from_ty. - let sig = Item::from_ty(&cursor.cur_type(), cursor, None, context)?; - - let mut name = cursor.spelling(); - assert!(!name.is_empty(), "Empty function name?"); - - if cursor.kind() == CXCursor_Destructor { - // Remove the leading `~`. The alternative to this is special-casing - // code-generation for destructor functions, which seems less than - // ideal. - if name.starts_with('~') { - name.remove(0); - } - - // Add a suffix to avoid colliding with constructors. This would be - // technically fine (since we handle duplicated functions/methods), - // but seems easy enough to handle it here. - name.push_str("_destructor"); - } - - let mangled_name = cursor_mangling(context, &cursor); - let comment = cursor.raw_comment(); - - let function = - Self::new(name, mangled_name, sig, comment, kind, linkage); - Ok(ParseResult::New(function, Some(cursor))) - } -} - -impl Trace for FunctionSig { - type Extra = (); - - fn trace(&self, _: &BindgenContext, tracer: &mut T, _: &()) - where - T: Tracer, - { - tracer.visit_kind(self.return_type().into(), EdgeKind::FunctionReturn); - - for &(_, ty) in self.argument_types() { - tracer.visit_kind(ty.into(), EdgeKind::FunctionParameter); - } - } -} diff --git a/src/ir/item_kind.rs b/src/ir/item_kind.rs deleted file mode 100644 index 4a12fef40d..0000000000 --- a/src/ir/item_kind.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! Different variants of an `Item` in our intermediate representation. - -use super::context::BindgenContext; -use super::dot::DotAttributes; -use super::function::Function; -use super::module::Module; -use super::ty::Type; -use super::var::Var; -use std::io; - -/// A item we parse and translate. -#[derive(Debug)] -pub enum ItemKind { - /// A module, created implicitly once (the root module), or via C++ - /// namespaces. - Module(Module), - - /// A type declared in any of the multiple ways it can be declared. - Type(Type), - - /// A function or method declaration. - Function(Function), - - /// A variable declaration, most likely a static. - Var(Var), -} - -impl ItemKind { - /// Get a reference to this `ItemKind`'s underying `Module`, or `None` if it - /// is some other kind. - pub fn as_module(&self) -> Option<&Module> { - match *self { - ItemKind::Module(ref module) => Some(module), - _ => None, - } - } - - /// Transform our `ItemKind` into a string. - pub fn kind_name(&self) -> &'static str { - match *self { - ItemKind::Module(..) => "Module", - ItemKind::Type(..) => "Type", - ItemKind::Function(..) => "Function", - ItemKind::Var(..) => "Var", - } - } - - /// Is this a module? - pub fn is_module(&self) -> bool { - self.as_module().is_some() - } - - /// Get a reference to this `ItemKind`'s underying `Module`, or panic if it - /// is some other kind. - pub fn expect_module(&self) -> &Module { - self.as_module().expect("Not a module") - } - - /// Get a reference to this `ItemKind`'s underying `Function`, or `None` if - /// it is some other kind. - pub fn as_function(&self) -> Option<&Function> { - match *self { - ItemKind::Function(ref func) => Some(func), - _ => None, - } - } - - /// Is this a function? - pub fn is_function(&self) -> bool { - self.as_function().is_some() - } - - /// Get a reference to this `ItemKind`'s underying `Function`, or panic if - /// it is some other kind. - pub fn expect_function(&self) -> &Function { - self.as_function().expect("Not a function") - } - - /// Get a reference to this `ItemKind`'s underying `Type`, or `None` if - /// it is some other kind. - pub fn as_type(&self) -> Option<&Type> { - match *self { - ItemKind::Type(ref ty) => Some(ty), - _ => None, - } - } - - /// Get a mutable reference to this `ItemKind`'s underying `Type`, or `None` - /// if it is some other kind. - pub fn as_type_mut(&mut self) -> Option<&mut Type> { - match *self { - ItemKind::Type(ref mut ty) => Some(ty), - _ => None, - } - } - - /// Is this a type? - pub fn is_type(&self) -> bool { - self.as_type().is_some() - } - - /// Get a reference to this `ItemKind`'s underying `Type`, or panic if it is - /// some other kind. - pub fn expect_type(&self) -> &Type { - self.as_type().expect("Not a type") - } - - /// Get a reference to this `ItemKind`'s underying `Var`, or `None` if it is - /// some other kind. - pub fn as_var(&self) -> Option<&Var> { - match *self { - ItemKind::Var(ref v) => Some(v), - _ => None, - } - } - - /// Is this a variable? - pub fn is_var(&self) -> bool { - self.as_var().is_some() - } - - /// Get a reference to this `ItemKind`'s underying `Var`, or panic if it is - /// some other kind. - pub fn expect_var(&self) -> &Var { - self.as_var().expect("Not a var") - } -} - -impl DotAttributes for ItemKind { - fn dot_attributes( - &self, - ctx: &BindgenContext, - out: &mut W, - ) -> io::Result<()> - where - W: io::Write, - { - writeln!(out, "kind{}", self.kind_name())?; - - match *self { - ItemKind::Module(ref module) => module.dot_attributes(ctx, out), - ItemKind::Type(ref ty) => ty.dot_attributes(ctx, out), - ItemKind::Function(ref func) => func.dot_attributes(ctx, out), - ItemKind::Var(ref var) => var.dot_attributes(ctx, out), - } - } -} diff --git a/src/ir/layout.rs b/src/ir/layout.rs deleted file mode 100644 index 6cf91131bb..0000000000 --- a/src/ir/layout.rs +++ /dev/null @@ -1,143 +0,0 @@ -//! 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)] -pub struct Layout { - /// The size (in bytes) of this layout. - pub size: usize, - /// The alignment (in bytes) of this layout. - pub align: usize, - /// Whether this layout's members are packed or not. - pub packed: bool, -} - -#[test] -fn test_layout_for_size() { - use std::mem; - - let ptr_size = mem::size_of::<*mut ()>(); - assert_eq!( - Layout::for_size_internal(ptr_size, ptr_size), - Layout::new(ptr_size, ptr_size) - ); - assert_eq!( - Layout::for_size_internal(ptr_size, 3 * ptr_size), - Layout::new(3 * ptr_size, ptr_size) - ); -} - -impl Layout { - /// Gets the integer type name for a given known size. - pub fn known_type_for_size( - ctx: &BindgenContext, - size: usize, - ) -> Option<&'static str> { - Some(match size { - 16 if ctx.options().rust_features.i128_and_u128 => "u128", - 8 => "u64", - 4 => "u32", - 2 => "u16", - 1 => "u8", - _ => return None, - }) - } - - /// Construct a new `Layout` with the given `size` and `align`. It is not - /// packed. - pub fn new(size: usize, align: usize) -> Self { - Layout { - size, - align, - packed: false, - } - } - - fn for_size_internal(ptr_size: usize, size: usize) -> Self { - let mut next_align = 2; - while size % next_align == 0 && next_align <= ptr_size { - next_align *= 2; - } - Layout { - size, - align: next_align / 2, - packed: false, - } - } - - /// Creates a non-packed layout for a given size, trying to use the maximum - /// alignment possible. - pub fn for_size(ctx: &BindgenContext, size: usize) -> Self { - Self::for_size_internal(ctx.target_pointer_size(), size) - } - - /// Is this a zero-sized layout? - pub fn is_zero(&self) -> bool { - self.size == 0 && self.align == 0 - } - - /// Construct a zero-sized layout. - pub fn zero() -> Self { - Self::new(0, 0) - } - - /// Get this layout as an opaque type. - pub 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)] -pub struct Opaque(pub Layout); - -impl Opaque { - /// Construct a new opaque type from the given clang type. - pub 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 fn known_rust_type_for_array( - &self, - ctx: &BindgenContext, - ) -> Option<&'static str> { - 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 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 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/src/ir/mod.rs b/src/ir/mod.rs deleted file mode 100644 index 8f6a2dac88..0000000000 --- a/src/ir/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! The ir module defines bindgen's intermediate representation. -//! -//! Parsing C/C++ generates the IR, while code generation outputs Rust code from -//! the IR. - -pub mod analysis; -pub mod annotations; -pub mod comment; -pub mod comp; -pub mod context; -pub mod derive; -pub mod dot; -pub mod enum_ty; -pub mod function; -pub mod int; -pub mod item; -pub mod item_kind; -pub mod layout; -pub mod module; -pub mod objc; -pub mod template; -pub mod traversal; -pub mod ty; -pub mod var; diff --git a/src/ir/objc.rs b/src/ir/objc.rs deleted file mode 100644 index 0845ad0fde..0000000000 --- a/src/ir/objc.rs +++ /dev/null @@ -1,329 +0,0 @@ -//! Objective C types - -use super::context::{BindgenContext, ItemId}; -use super::function::FunctionSig; -use super::item::Item; -use super::traversal::{Trace, Tracer}; -use super::ty::TypeKind; -use crate::clang; -use crate::parse::ClangItemParser; -use clang_sys::CXChildVisit_Continue; -use clang_sys::CXCursor_ObjCCategoryDecl; -use clang_sys::CXCursor_ObjCClassMethodDecl; -use clang_sys::CXCursor_ObjCClassRef; -use clang_sys::CXCursor_ObjCInstanceMethodDecl; -use clang_sys::CXCursor_ObjCProtocolDecl; -use clang_sys::CXCursor_ObjCProtocolRef; -use clang_sys::CXCursor_ObjCSuperClassRef; -use clang_sys::CXCursor_TemplateTypeParameter; -use proc_macro2::{Ident, Span, TokenStream}; - -/// Objective C interface as used in TypeKind -/// -/// Also protocols and categories are parsed as this type -#[derive(Debug)] -pub struct ObjCInterface { - /// The name - /// like, NSObject - name: String, - - category: Option, - - is_protocol: bool, - - /// The list of template names almost always, ObjectType or KeyType - pub template_names: Vec, - - /// The list of protocols that this interface conforms to. - pub conforms_to: Vec, - - /// The direct parent for this interface. - pub parent_class: Option, - - /// List of the methods defined in this interfae - methods: Vec, - - class_methods: Vec, -} - -/// The objective c methods -#[derive(Debug)] -pub struct ObjCMethod { - /// The original method selector name - /// like, dataWithBytes:length: - name: String, - - /// Method name as converted to rust - /// like, dataWithBytes_length_ - rust_name: String, - - signature: FunctionSig, - - /// Is class method? - is_class_method: bool, -} - -impl ObjCInterface { - fn new(name: &str) -> ObjCInterface { - ObjCInterface { - name: name.to_owned(), - category: None, - is_protocol: false, - template_names: Vec::new(), - parent_class: None, - conforms_to: Vec::new(), - methods: Vec::new(), - class_methods: Vec::new(), - } - } - - /// The name - /// like, NSObject - pub 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 - pub fn rust_name(&self) -> String { - if let Some(ref cat) = self.category { - format!("{}_{}", self.name(), cat) - } else if self.is_protocol { - format!("P{}", self.name()) - } else { - format!("I{}", self.name().to_owned()) - } - } - - /// Is this a template interface? - pub fn is_template(&self) -> bool { - !self.template_names.is_empty() - } - - /// List of the methods defined in this interface - pub fn methods(&self) -> &Vec { - &self.methods - } - - /// Is this a protocol? - pub fn is_protocol(&self) -> bool { - self.is_protocol - } - - /// Is this a category? - pub fn is_category(&self) -> bool { - self.category.is_some() - } - - /// List of the class methods defined in this interface - pub fn class_methods(&self) -> &Vec { - &self.class_methods - } - - /// Parses the Objective C interface from the cursor - pub fn from_ty( - cursor: &clang::Cursor, - ctx: &mut BindgenContext, - ) -> Option { - let name = cursor.spelling(); - let mut interface = Self::new(&name); - - if cursor.kind() == CXCursor_ObjCProtocolDecl { - interface.is_protocol = true; - } - - cursor.visit(|c| { - match c.kind() { - CXCursor_ObjCClassRef => { - if cursor.kind() == CXCursor_ObjCCategoryDecl { - // We are actually a category extension, and we found the reference - // to the original interface, so name this interface approriately - interface.name = c.spelling(); - interface.category = Some(cursor.spelling()); - } - } - CXCursor_ObjCProtocolRef => { - // Gather protocols this interface conforms to - let needle = format!("P{}", c.spelling()); - let items_map = ctx.items(); - debug!( - "Interface {} conforms to {}, find the item", - interface.name, needle - ); - - for (id, item) in items_map { - if let Some(ty) = item.as_type() { - if let TypeKind::ObjCInterface(ref protocol) = - *ty.kind() - { - if protocol.is_protocol { - debug!( - "Checking protocol {}, ty.name {:?}", - protocol.name, - ty.name() - ); - if Some(needle.as_ref()) == ty.name() { - debug!( - "Found conforming protocol {:?}", - item - ); - interface.conforms_to.push(id); - break; - } - } - } - } - } - } - CXCursor_ObjCInstanceMethodDecl | - CXCursor_ObjCClassMethodDecl => { - let name = c.spelling(); - let signature = - FunctionSig::from_ty(&c.cur_type(), &c, ctx) - .expect("Invalid function sig"); - let is_class_method = - c.kind() == CXCursor_ObjCClassMethodDecl; - let method = - ObjCMethod::new(&name, signature, is_class_method); - interface.add_method(method); - } - CXCursor_TemplateTypeParameter => { - let name = c.spelling(); - interface.template_names.push(name); - } - CXCursor_ObjCSuperClassRef => { - let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx); - interface.parent_class = Some(item.into()); - } - _ => {} - } - CXChildVisit_Continue - }); - Some(interface) - } - - fn add_method(&mut self, method: ObjCMethod) { - if method.is_class_method { - self.class_methods.push(method); - } else { - self.methods.push(method); - } - } -} - -impl ObjCMethod { - fn new( - name: &str, - signature: FunctionSig, - is_class_method: bool, - ) -> ObjCMethod { - let split_name: Vec<&str> = name.split(':').collect(); - - let rust_name = split_name.join("_"); - - ObjCMethod { - name: name.to_owned(), - rust_name, - signature, - is_class_method, - } - } - - /// The original method selector name - /// like, dataWithBytes:length: - pub fn name(&self) -> &str { - self.name.as_ref() - } - - /// Method name as converted to rust - /// like, dataWithBytes_length_ - pub fn rust_name(&self) -> &str { - self.rust_name.as_ref() - } - - /// Returns the methods signature as FunctionSig - pub fn signature(&self) -> &FunctionSig { - &self.signature - } - - /// Is this a class method? - pub fn is_class_method(&self) -> bool { - self.is_class_method - } - - /// Formats the method call - pub fn format_method_call(&self, args: &[TokenStream]) -> TokenStream { - let split_name: Vec> = self - .name - .split(':') - .map(|name| { - if name.is_empty() { - None - } else { - Some(Ident::new(name, Span::call_site())) - } - }) - .collect(); - - // No arguments - if args.is_empty() && split_name.len() == 1 { - let name = &split_name[0]; - return quote! { - #name - }; - } - - // Check right amount of arguments - assert!( - args.len() == split_name.len() - 1, - "Incorrect method name or arguments for objc method, {:?} vs {:?}", - args, - split_name - ); - - // Get arguments without type signatures to pass to `msg_send!` - let mut args_without_types = vec![]; - for arg in args.iter() { - 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())) - } - - let args = split_name.into_iter().zip(args_without_types).map( - |(arg, arg_val)| { - if let Some(arg) = arg { - quote! { #arg: #arg_val } - } else { - quote! { #arg_val: #arg_val } - } - }, - ); - - quote! { - #( #args )* - } - } -} - -impl Trace for ObjCInterface { - type Extra = (); - - fn trace(&self, context: &BindgenContext, tracer: &mut T, _: &()) - where - T: Tracer, - { - for method in &self.methods { - method.signature.trace(context, tracer, &()); - } - - for class_method in &self.class_methods { - class_method.signature.trace(context, tracer, &()); - } - - for protocol in &self.conforms_to { - tracer.visit(*protocol); - } - } -} diff --git a/src/ir/template.rs b/src/ir/template.rs deleted file mode 100644 index 8b06748e2c..0000000000 --- a/src/ir/template.rs +++ /dev/null @@ -1,343 +0,0 @@ -//! Template declaration and instantiation related things. -//! -//! The nomenclature surrounding templates is often confusing, so here are a few -//! brief definitions: -//! -//! * "Template definition": a class/struct/alias/function definition that takes -//! generic template parameters. For example: -//! -//! ```c++ -//! template -//! class List { -//! // ... -//! }; -//! ``` -//! -//! * "Template instantiation": an instantiation is a use of a template with -//! concrete template arguments. For example, `List`. -//! -//! * "Template specialization": an alternative template definition providing a -//! custom definition for instantiations with the matching template -//! arguments. This C++ feature is unsupported by bindgen. For example: -//! -//! ```c++ -//! template<> -//! class List { -//! // Special layout for int lists... -//! }; -//! ``` - -use super::context::{BindgenContext, ItemId, TypeId}; -use super::item::{IsOpaque, Item, ItemAncestors}; -use super::traversal::{EdgeKind, Trace, Tracer}; -use crate::clang; -use crate::parse::ClangItemParser; - -/// Template declaration (and such declaration's template parameters) related -/// methods. -/// -/// This trait's methods distinguish between `None` and `Some([])` for -/// declarations that are not templates and template declarations with zero -/// parameters, in general. -/// -/// Consider this example: -/// -/// ```c++ -/// template -/// class Foo { -/// T use_of_t; -/// U use_of_u; -/// -/// template -/// using Bar = V*; -/// -/// class Inner { -/// T x; -/// U y; -/// Bar z; -/// }; -/// -/// template -/// class Lol { -/// // No use of W, but here's a use of T. -/// T t; -/// }; -/// -/// template -/// class Wtf { -/// // X is not used because W is not used. -/// Lol lololol; -/// }; -/// }; -/// -/// class Qux { -/// int y; -/// }; -/// ``` -/// -/// 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. | ... | used_template_params | -/// ----+------+-----+----------------------+ -/// ... |Foo | ... | [T, U] | -/// ... |Bar | ... | [V] | -/// ... |Inner | ... | [] | -/// ... |Lol | ... | [T] | -/// ... |Wtf | ... | [T] | -/// ... |Qux | ... | [] | -/// ----+------+-----+----------------------+ -pub trait TemplateParameters: Sized { - /// Get the set of `ItemId`s that make up this template declaration's free - /// template parameters. - /// - /// Note that these might *not* all be named types: C++ allows - /// constant-value template parameters as well as template-template - /// parameters. Of course, Rust does not allow generic parameters to be - /// anything but types, so we must treat them as opaque, and avoid - /// instantiating them. - fn self_template_params(&self, ctx: &BindgenContext) -> Vec; - - /// Get the number of free template parameters this template declaration - /// has. - fn num_self_template_params(&self, ctx: &BindgenContext) -> usize { - self.self_template_params(ctx).len() - } - - /// Get the complete set of template parameters that can affect this - /// declaration. - /// - /// Note that this item doesn't need to be a template declaration itself for - /// `Some` to be returned here (in contrast to `self_template_params`). If - /// this item is a member of a template declaration, then the parent's - /// template parameters are included here. - /// - /// In the example above, `Inner` depends on both of the `T` and `U` type - /// parameters, even though it is not itself a template declaration and - /// therefore has no type parameters itself. Perhaps it helps to think about - /// how we would fully reference such a member type in C++: - /// `Foo::Inner`. `Foo` *must* be instantiated with template - /// arguments before we can gain access to the `Inner` member type. - fn all_template_params(&self, ctx: &BindgenContext) -> Vec - where - Self: ItemAncestors, - { - let mut ancestors: Vec<_> = self.ancestors(ctx).collect(); - ancestors.reverse(); - ancestors - .into_iter() - .flat_map(|id| id.self_template_params(ctx).into_iter()) - .collect() - } - - /// Get only the set of template parameters that this item uses. This is a - /// subset of `all_template_params` and does not necessarily contain any of - /// `self_template_params`. - fn used_template_params(&self, ctx: &BindgenContext) -> Vec - where - Self: AsRef, - { - assert!( - ctx.in_codegen_phase(), - "template parameter usage is not computed until codegen" - ); - - let id = *self.as_ref(); - ctx.resolve_item(id) - .all_template_params(ctx) - .into_iter() - .filter(|p| ctx.uses_template_parameter(id, *p)) - .collect() - } -} - -/// A trait for things which may or may not be a named template type parameter. -pub trait AsTemplateParam { - /// Any extra information the implementor might need to make this decision. - type Extra; - - /// Convert this thing to the item id of a named template type parameter. - fn as_template_param( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> Option; - - /// Is this a named template type parameter? - fn is_template_param( - &self, - ctx: &BindgenContext, - extra: &Self::Extra, - ) -> bool { - self.as_template_param(ctx, extra).is_some() - } -} - -/// A concrete instantiation of a generic template. -#[derive(Clone, Debug)] -pub struct TemplateInstantiation { - /// The template definition which this is instantiating. - definition: TypeId, - /// The concrete template arguments, which will be substituted in the - /// definition for the generic template parameters. - args: Vec, -} - -impl TemplateInstantiation { - /// Construct a new template instantiation from the given parts. - pub fn new(definition: TypeId, args: I) -> TemplateInstantiation - where - I: IntoIterator, - { - TemplateInstantiation { - definition, - args: args.into_iter().collect(), - } - } - - /// Get the template definition for this instantiation. - pub fn template_definition(&self) -> TypeId { - self.definition - } - - /// Get the concrete template arguments used in this instantiation. - pub fn template_arguments(&self) -> &[TypeId] { - &self.args[..] - } - - /// Parse a `TemplateInstantiation` from a clang `Type`. - pub fn from_ty( - ty: &clang::Type, - ctx: &mut BindgenContext, - ) -> Option { - use clang_sys::*; - - let template_args = ty.template_args().map_or(vec![], |args| match ty - .canonical_type() - .template_args() - { - Some(canonical_args) => { - let arg_count = args.len(); - args.chain(canonical_args.skip(arg_count)) - .filter(|t| t.kind() != CXType_Invalid) - .map(|t| { - Item::from_ty_or_ref(t, t.declaration(), None, ctx) - }) - .collect() - } - None => args - .filter(|t| t.kind() != CXType_Invalid) - .map(|t| Item::from_ty_or_ref(t, t.declaration(), None, ctx)) - .collect(), - }); - - let declaration = ty.declaration(); - let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl - { - Some(declaration) - } else { - declaration.specialized().or_else(|| { - let mut template_ref = None; - ty.declaration().visit(|child| { - if child.kind() == CXCursor_TemplateRef { - template_ref = Some(child); - return CXVisit_Break; - } - - // Instantiations of template aliases might have the - // TemplateRef to the template alias definition arbitrarily - // deep, so we need to recurse here and not only visit - // direct children. - CXChildVisit_Recurse - }); - - template_ref.and_then(|cur| cur.referenced()) - }) - }; - - let definition = match definition { - Some(def) => def, - None => { - if !ty.declaration().is_builtin() { - warn!( - "Could not find template definition for template \ - instantiation" - ); - } - return None; - } - }; - - let template_definition = - Item::from_ty_or_ref(definition.cur_type(), definition, None, ctx); - - Some(TemplateInstantiation::new( - template_definition, - template_args, - )) - } -} - -impl IsOpaque for TemplateInstantiation { - type Extra = Item; - - /// Is this an opaque template instantiation? - fn is_opaque(&self, ctx: &BindgenContext, item: &Item) -> bool { - if self.template_definition().is_opaque(ctx, &()) { - return true; - } - - // TODO(#774): This doesn't properly handle opaque instantiations where - // an argument is itself an instantiation because `canonical_name` does - // not insert the template arguments into the name, ie it for nested - // template arguments it creates "Foo" instead of "Foo". The fully - // correct fix is to make `canonical_{name,path}` include template - // arguments properly. - - let mut path = item.path_for_allowlisting(ctx).clone(); - let args: Vec<_> = self - .template_arguments() - .iter() - .map(|arg| { - let arg_path = - ctx.resolve_item(*arg).path_for_allowlisting(ctx); - arg_path[1..].join("::") - }) - .collect(); - { - let last = path.last_mut().unwrap(); - last.push('<'); - last.push_str(&args.join(", ")); - last.push('>'); - } - - ctx.opaque_by_name(&path) - } -} - -impl Trace for TemplateInstantiation { - type Extra = (); - - fn trace(&self, _ctx: &BindgenContext, tracer: &mut T, _: &()) - where - T: Tracer, - { - tracer - .visit_kind(self.definition.into(), EdgeKind::TemplateDeclaration); - for arg in self.template_arguments() { - tracer.visit_kind(arg.into(), EdgeKind::TemplateArgument); - } - } -} diff --git a/src/ir/var.rs b/src/ir/var.rs deleted file mode 100644 index e44d57afe4..0000000000 --- a/src/ir/var.rs +++ /dev/null @@ -1,417 +0,0 @@ -//! Intermediate representation of variables. - -use super::super::codegen::MacroTypeVariation; -use super::context::{BindgenContext, TypeId}; -use super::dot::DotAttributes; -use super::function::cursor_mangling; -use super::int::IntKind; -use super::item::Item; -use super::ty::{FloatKind, TypeKind}; -use crate::callbacks::MacroParsingBehavior; -use crate::clang; -use crate::clang::ClangToken; -use crate::parse::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; -use cexpr; -use std::io; -use std::num::Wrapping; - -/// The type for a constant variable. -#[derive(Debug)] -pub enum VarType { - /// A boolean. - Bool(bool), - /// An integer. - Int(i64), - /// A floating point number. - Float(f64), - /// A character. - Char(u8), - /// A string, not necessarily well-formed utf-8. - String(Vec), -} - -/// A `Var` is our intermediate representation of a variable. -#[derive(Debug)] -pub struct Var { - /// The name of the variable. - name: String, - /// The mangled name of the variable. - mangled_name: Option, - /// The type of the variable. - ty: TypeId, - /// The value of the variable, that needs to be suitable for `ty`. - val: Option, - /// Whether this variable is const. - is_const: bool, -} - -impl Var { - /// Construct a new `Var`. - pub fn new( - name: String, - mangled_name: Option, - ty: TypeId, - val: Option, - is_const: bool, - ) -> Var { - assert!(!name.is_empty()); - Var { - name, - mangled_name, - ty, - val, - is_const, - } - } - - /// Is this variable `const` qualified? - pub fn is_const(&self) -> bool { - self.is_const - } - - /// The value of this constant variable, if any. - pub fn val(&self) -> Option<&VarType> { - self.val.as_ref() - } - - /// Get this variable's type. - pub fn ty(&self) -> TypeId { - self.ty - } - - /// Get this variable's name. - pub fn name(&self) -> &str { - &self.name - } - - /// Get this variable's mangled name. - pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_deref() - } -} - -impl DotAttributes for Var { - fn dot_attributes( - &self, - _ctx: &BindgenContext, - out: &mut W, - ) -> io::Result<()> - where - W: io::Write, - { - if self.is_const { - writeln!(out, "consttrue")?; - } - - if let Some(ref mangled) = self.mangled_name { - writeln!( - out, - "mangled name{}", - mangled - )?; - } - - Ok(()) - } -} - -fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { - if value < 0 || - ctx.options().default_macro_constant_type == - MacroTypeVariation::Signed - { - if value < i32::min_value() as i64 || value > i32::max_value() as i64 { - IntKind::I64 - } else if !ctx.options().fit_macro_constants || - value < i16::min_value() as i64 || - value > i16::max_value() as i64 - { - IntKind::I32 - } else if value < i8::min_value() as i64 || - value > i8::max_value() as i64 - { - IntKind::I16 - } else { - IntKind::I8 - } - } else if value > u32::max_value() as i64 { - IntKind::U64 - } else if !ctx.options().fit_macro_constants || - value > u16::max_value() as i64 - { - IntKind::U32 - } else if value > u8::max_value() as i64 { - IntKind::U16 - } else { - IntKind::U8 - } -} - -/// 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, -) { - let is_closing_paren = |t: &ClangToken| { - // Test cheap token kind before comparing exact spellings. - t.kind == clang_sys::CXToken_Punctuation && t.spelling() == b")" - }; - let tokens: Vec<_> = cursor.tokens().iter().collect(); - if let Some(boundary) = tokens.iter().position(is_closing_paren) { - let mut spelled = tokens.iter().map(ClangToken::spelling); - // Add 1, to convert index to length. - let left = spelled.by_ref().take(boundary + 1); - let left = left.collect::>().concat(); - if let Ok(left) = String::from_utf8(left) { - let right: Vec<_> = spelled.collect(); - callbacks.func_macro(&left, &right); - } - } -} - -impl ClangSubItemParser for Var { - fn parse( - cursor: clang::Cursor, - ctx: &mut BindgenContext, - ) -> Result, ParseError> { - use cexpr::expr::EvalResult; - use cexpr::literal::CChar; - use clang_sys::*; - match cursor.kind() { - CXCursor_MacroDefinition => { - if let Some(callbacks) = ctx.parse_callbacks() { - match callbacks.will_parse_macro(&cursor.spelling()) { - MacroParsingBehavior::Ignore => { - return Err(ParseError::Continue); - } - MacroParsingBehavior::Default => {} - } - - if cursor.is_macro_function_like() { - handle_function_macro(&cursor, callbacks); - // We handled the macro, skip macro processing below. - return Err(ParseError::Continue); - } - } - - let value = parse_macro(ctx, &cursor); - - let (id, value) = match value { - Some(v) => v, - None => return Err(ParseError::Continue), - }; - - assert!(!id.is_empty(), "Empty macro name?"); - - let previously_defined = ctx.parsed_macro(&id); - - // NB: It's important to "note" the macro even if the result is - // not an integer, otherwise we might loose other kind of - // derived macros. - ctx.note_parsed_macro(id.clone(), value.clone()); - - if previously_defined { - let name = String::from_utf8(id).unwrap(); - warn!("Duplicated macro definition: {}", name); - return Err(ParseError::Continue); - } - - // NOTE: Unwrapping, here and above, is safe, because the - // identifier of a token comes straight from clang, and we - // enforce utf8 there, so we should have already panicked at - // this point. - let name = String::from_utf8(id).unwrap(); - let (type_kind, val) = match value { - EvalResult::Invalid => return Err(ParseError::Continue), - EvalResult::Float(f) => { - (TypeKind::Float(FloatKind::Double), VarType::Float(f)) - } - EvalResult::Char(c) => { - let c = match c { - CChar::Char(c) => { - assert_eq!(c.len_utf8(), 1); - c as u8 - } - CChar::Raw(c) => { - assert!(c <= ::std::u8::MAX as u64); - c as u8 - } - }; - - (TypeKind::Int(IntKind::U8), VarType::Char(c)) - } - EvalResult::Str(val) => { - let char_ty = Item::builtin_type( - TypeKind::Int(IntKind::U8), - true, - ctx, - ); - if let Some(callbacks) = ctx.parse_callbacks() { - callbacks.str_macro(&name, &val); - } - (TypeKind::Pointer(char_ty), VarType::String(val)) - } - EvalResult::Int(Wrapping(value)) => { - let kind = ctx - .parse_callbacks() - .and_then(|c| c.int_macro(&name, value)) - .unwrap_or_else(|| { - default_macro_constant_type(ctx, value) - }); - - (TypeKind::Int(kind), VarType::Int(value)) - } - }; - - let ty = Item::builtin_type(type_kind, true, ctx); - - Ok(ParseResult::New( - Var::new(name, None, ty, Some(val), true), - Some(cursor), - )) - } - CXCursor_VarDecl => { - let name = cursor.spelling(); - if name.is_empty() { - warn!("Empty constant name?"); - return Err(ParseError::Continue); - } - - let ty = cursor.cur_type(); - - // TODO(emilio): do we have to special-case constant arrays in - // some other places? - let is_const = ty.is_const() || - (ty.kind() == CXType_ConstantArray && - ty.elem_type() - .map_or(false, |element| element.is_const())); - - let ty = match Item::from_ty(&ty, cursor, None, ctx) { - Ok(ty) => ty, - Err(e) => { - assert_eq!( - ty.kind(), - CXType_Auto, - "Couldn't resolve constant type, and it \ - wasn't an nondeductible auto type!" - ); - return Err(e); - } - }; - - // Note: Ty might not be totally resolved yet, see - // tests/headers/inner_const.hpp - // - // That's fine because in that case we know it's not a literal. - let canonical_ty = ctx - .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()); - - // 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 mut val = cursor.evaluate().and_then(|v| v.as_int()); - if val.is_none() || !kind.signedness_matches(val.unwrap()) { - let tu = ctx.translation_unit(); - val = get_integer_literal_from_cursor(&cursor, tu); - } - - val.map(|val| { - if kind == IntKind::Bool { - VarType::Bool(val != 0) - } else { - VarType::Int(val) - } - }) - } else if is_float { - cursor - .evaluate() - .and_then(|v| v.as_double()) - .map(VarType::Float) - } else { - cursor - .evaluate() - .and_then(|v| v.as_literal_string()) - .map(VarType::String) - }; - - let mangling = cursor_mangling(ctx, &cursor); - let var = Var::new(name, mangling, ty, value, is_const); - - Ok(ParseResult::New(var, Some(cursor))) - } - _ => { - /* TODO */ - Err(ParseError::Continue) - } - } - } -} - -/// Try and parse a macro using all the macros parsed until now. -fn parse_macro( - ctx: &BindgenContext, - cursor: &clang::Cursor, -) -> Option<(Vec, cexpr::expr::EvalResult)> { - use cexpr::expr; - - let cexpr_tokens = cursor.cexpr_tokens(); - - let parser = expr::IdentifierParser::new(ctx.parsed_macros()); - - match parser.macro_definition(&cexpr_tokens) { - Ok((_, (id, val))) => Some((id.into(), val)), - _ => None, - } -} - -fn parse_int_literal_tokens(cursor: &clang::Cursor) -> Option { - use cexpr::expr; - use cexpr::expr::EvalResult; - - let cexpr_tokens = cursor.cexpr_tokens(); - - // TODO(emilio): We can try to parse other kinds of literals. - match expr::expr(&cexpr_tokens) { - Ok((_, EvalResult::Int(Wrapping(val)))) => Some(val), - _ => None, - } -} - -fn get_integer_literal_from_cursor( - cursor: &clang::Cursor, - unit: &clang::TranslationUnit, -) -> Option { - use clang_sys::*; - let mut value = None; - cursor.visit(|c| { - match c.kind() { - CXCursor_IntegerLiteral | CXCursor_UnaryOperator => { - value = parse_int_literal_tokens(&c); - } - CXCursor_UnexposedExpr => { - value = get_integer_literal_from_cursor(&c, unit); - } - _ => (), - } - if value.is_some() { - CXChildVisit_Break - } else { - CXChildVisit_Continue - } - }); - value -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 0742217fe1..0000000000 --- a/src/lib.rs +++ /dev/null @@ -1,2802 +0,0 @@ -//! Generate Rust bindings for C and C++ libraries. -//! -//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++ -//! functions and use types defined in the header. -//! -//! See the [`Builder`](./struct.Builder.html) struct for usage. -//! -//! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for -//! additional documentation. -#![deny(missing_docs)] -#![deny(unused_extern_crates)] -// To avoid rather annoying warnings when matching with CXCursor_xxx as a -// constant. -#![allow(non_upper_case_globals)] -// `quote!` nests quite deeply. -#![recursion_limit = "128"] - -#[macro_use] -extern crate bitflags; -#[macro_use] -extern crate lazy_static; -#[macro_use] -extern crate quote; - -#[cfg(feature = "logging")] -#[macro_use] -extern crate log; - -#[cfg(not(feature = "logging"))] -#[macro_use] -mod log_stubs; - -#[macro_use] -mod extra_assertions; - -// A macro to declare an internal module for which we *must* provide -// documentation for. If we are building with the "testing_only_docs" feature, -// then the module is declared public, and our `#![deny(missing_docs)]` pragma -// applies to it. This feature is used in CI, so we won't let anything slip by -// undocumented. Normal builds, however, will leave the module private, so that -// we don't expose internals to library consumers. -macro_rules! doc_mod { - ($m:ident, $doc_mod_name:ident) => { - #[cfg(feature = "testing_only_docs")] - pub mod $doc_mod_name { - //! Autogenerated documentation module. - pub use super::$m::*; - } - }; -} - -mod clang; -mod codegen; -mod deps; -mod features; -mod ir; -mod parse; -mod regex_set; -mod time; - -pub mod callbacks; - -doc_mod!(clang, clang_docs); -doc_mod!(features, features_docs); -doc_mod!(ir, ir_docs); -doc_mod!(parse, parse_docs); -doc_mod!(regex_set, regex_set_docs); - -pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation}; -use crate::features::RustFeatures; -pub use crate::features::{ - RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS, -}; -use crate::ir::context::{BindgenContext, ItemId}; -use crate::ir::item::Item; -use crate::parse::{ClangItemParser, ParseError}; -use crate::regex_set::RegexSet; - -use std::borrow::Cow; -use std::fs::{File, OpenOptions}; -use std::io::{self, Write}; -use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; -use std::{env, iter}; - -// Some convenient typedefs for a fast hash map and hash set. -type HashMap = ::rustc_hash::FxHashMap; -type HashSet = ::rustc_hash::FxHashSet; -pub(crate) use std::collections::hash_map::Entry; - -/// Default prefix for the anon fields. -pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_"; - -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++") -} - -fn args_are_cpp(clang_args: &[String]) -> bool { - for w in clang_args.windows(2) { - if w[0] == "-xc++" || w[1] == "-xc++" { - return true; - } - if w[0] == "-x" && w[1] == "c++" { - return true; - } - if w[0] == "-include" && file_is_cpp(&w[1]) { - return true; - } - } - false -} - -bitflags! { - /// A type used to indicate which kind of items we have to generate. - pub struct CodegenConfig: u32 { - /// Whether to generate functions. - const FUNCTIONS = 1 << 0; - /// Whether to generate types. - const TYPES = 1 << 1; - /// Whether to generate constants. - const VARS = 1 << 2; - /// Whether to generate methods. - const METHODS = 1 << 3; - /// Whether to generate constructors - const CONSTRUCTORS = 1 << 4; - /// Whether to generate destructors. - const DESTRUCTORS = 1 << 5; - } -} - -impl CodegenConfig { - /// Returns true if functions should be generated. - pub fn functions(self) -> bool { - self.contains(CodegenConfig::FUNCTIONS) - } - - /// Returns true if types should be generated. - pub fn types(self) -> bool { - self.contains(CodegenConfig::TYPES) - } - - /// Returns true if constants should be generated. - pub fn vars(self) -> bool { - self.contains(CodegenConfig::VARS) - } - - /// Returns true if methds should be generated. - pub fn methods(self) -> bool { - self.contains(CodegenConfig::METHODS) - } - - /// Returns true if constructors should be generated. - pub fn constructors(self) -> bool { - self.contains(CodegenConfig::CONSTRUCTORS) - } - - /// Returns true if destructors should be generated. - pub fn destructors(self) -> bool { - self.contains(CodegenConfig::DESTRUCTORS) - } -} - -impl Default for CodegenConfig { - fn default() -> Self { - CodegenConfig::all() - } -} - -/// Configure and generate Rust bindings for a C/C++ header. -/// -/// This is the main entry point to the library. -/// -/// ```ignore -/// use bindgen::builder; -/// -/// // Configure and generate bindings. -/// let bindings = builder().header("path/to/input/header") -/// .allowlist_type("SomeCoolClass") -/// .allowlist_function("do_some_cool_thing") -/// .generate()?; -/// -/// // Write the generated bindings to an output file. -/// bindings.write_to_file("path/to/output.rs")?; -/// ``` -/// -/// # Enums -/// -/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on -/// the pattern passed to several methods: -/// -/// 1. [`constified_enum_module()`](#method.constified_enum_module) -/// 2. [`bitfield_enum()`](#method.bitfield_enum) -/// 3. [`newtype_enum()`](#method.newtype_enum) -/// 4. [`rustified_enum()`](#method.rustified_enum) -/// -/// For each C enum, bindgen tries to match the pattern in the following order: -/// -/// 1. Constified enum module -/// 2. Bitfield enum -/// 3. Newtype enum -/// 4. Rustified enum -/// -/// If none of the above patterns match, then bindgen will generate a set of Rust constants. -/// -/// # Clang arguments -/// -/// Extra arguments can be passed to with clang: -/// 1. [`clang_arg()`](#method.clang_arg): takes a single argument -/// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments -/// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate -/// environment variable of arguments -/// -/// Clang arguments specific to your crate should be added via the -/// `clang_arg()`/`clang_args()` methods. -/// -/// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to -/// add additional arguments. For example, to build against a different sysroot a user could set -/// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`. -#[derive(Debug, Default)] -pub struct Builder { - options: BindgenOptions, - input_headers: Vec, - // Tuples of unsaved file contents of the form (name, contents). - input_header_contents: Vec<(String, String)>, -} - -/// Construct a new [`Builder`](./struct.Builder.html). -pub fn builder() -> Builder { - Default::default() -} - -fn get_extra_clang_args() -> Vec { - // Add any extra arguments from the environment to the clang command line. - let extra_clang_args = - match get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS") { - None => return vec![], - Some(s) => s, - }; - // Try to parse it with shell quoting. If we fail, make it one single big argument. - if let Some(strings) = shlex::split(&extra_clang_args) { - return strings; - } - vec![extra_clang_args] -} - -impl Builder { - /// Generates the command line flags use for creating `Builder`. - pub fn command_line_flags(&self) -> Vec { - let mut output_vector: Vec = Vec::new(); - - if let Some(header) = self.input_headers.last().cloned() { - // Positional argument 'header' - output_vector.push(header); - } - - output_vector.push("--rust-target".into()); - output_vector.push(self.options.rust_target.into()); - - // FIXME(emilio): This is a bit hacky, maybe we should stop re-using the - // RustFeatures to store the "disable_untagged_union" call, and make it - // a different flag that we check elsewhere / in generate(). - if !self.options.rust_features.untagged_union && - RustFeatures::from(self.options.rust_target).untagged_union - { - output_vector.push("--disable-untagged-union".into()); - } - - if self.options.default_enum_style != Default::default() { - output_vector.push("--default-enum-style".into()); - output_vector.push( - match self.options.default_enum_style { - codegen::EnumVariation::Rust { - non_exhaustive: false, - } => "rust", - codegen::EnumVariation::Rust { - non_exhaustive: true, - } => "rust_non_exhaustive", - codegen::EnumVariation::NewType { is_bitfield: true } => { - "bitfield" - } - codegen::EnumVariation::NewType { is_bitfield: false } => { - "newtype" - } - codegen::EnumVariation::Consts => "consts", - codegen::EnumVariation::ModuleConsts => "moduleconsts", - } - .into(), - ) - } - - if self.options.default_macro_constant_type != Default::default() { - output_vector.push("--default-macro-constant-type".into()); - output_vector - .push(self.options.default_macro_constant_type.as_str().into()); - } - - if self.options.default_alias_style != Default::default() { - output_vector.push("--default-alias-style".into()); - output_vector - .push(self.options.default_alias_style.as_str().into()); - } - - let regex_sets = &[ - (&self.options.bitfield_enums, "--bitfield-enum"), - (&self.options.newtype_enums, "--newtype-enum"), - (&self.options.rustified_enums, "--rustified-enum"), - ( - &self.options.rustified_non_exhaustive_enums, - "--rustified-enum-non-exhaustive", - ), - ( - &self.options.constified_enum_modules, - "--constified-enum-module", - ), - (&self.options.constified_enums, "--constified-enum"), - (&self.options.type_alias, "--type-alias"), - (&self.options.new_type_alias, "--new-type-alias"), - (&self.options.new_type_alias_deref, "--new-type-alias-deref"), - (&self.options.blocklisted_types, "--blocklist-type"), - (&self.options.blocklisted_functions, "--blocklist-function"), - (&self.options.blocklisted_items, "--blocklist-item"), - (&self.options.blocklisted_files, "--blocklist-file"), - (&self.options.opaque_types, "--opaque-type"), - (&self.options.allowlisted_functions, "--allowlist-function"), - (&self.options.allowlisted_types, "--allowlist-type"), - (&self.options.allowlisted_vars, "--allowlist-var"), - (&self.options.allowlisted_files, "--allowlist-file"), - (&self.options.no_partialeq_types, "--no-partialeq"), - (&self.options.no_copy_types, "--no-copy"), - (&self.options.no_debug_types, "--no-debug"), - (&self.options.no_default_types, "--no-default"), - (&self.options.no_hash_types, "--no-hash"), - (&self.options.must_use_types, "--must-use-type"), - ]; - - for (set, flag) in regex_sets { - for item in set.get_items() { - output_vector.push((*flag).to_owned()); - output_vector.push(item.to_owned()); - } - } - - if !self.options.layout_tests { - output_vector.push("--no-layout-tests".into()); - } - - if self.options.impl_debug { - output_vector.push("--impl-debug".into()); - } - - if self.options.impl_partialeq { - output_vector.push("--impl-partialeq".into()); - } - - if !self.options.derive_copy { - output_vector.push("--no-derive-copy".into()); - } - - if !self.options.derive_debug { - output_vector.push("--no-derive-debug".into()); - } - - if !self.options.derive_default { - output_vector.push("--no-derive-default".into()); - } else { - output_vector.push("--with-derive-default".into()); - } - - if self.options.derive_hash { - output_vector.push("--with-derive-hash".into()); - } - - if self.options.derive_partialord { - output_vector.push("--with-derive-partialord".into()); - } - - if self.options.derive_ord { - output_vector.push("--with-derive-ord".into()); - } - - if self.options.derive_partialeq { - output_vector.push("--with-derive-partialeq".into()); - } - - if self.options.derive_eq { - output_vector.push("--with-derive-eq".into()); - } - - if self.options.time_phases { - output_vector.push("--time-phases".into()); - } - - if !self.options.generate_comments { - output_vector.push("--no-doc-comments".into()); - } - - if !self.options.allowlist_recursively { - output_vector.push("--no-recursive-allowlist".into()); - } - - if self.options.objc_extern_crate { - output_vector.push("--objc-extern-crate".into()); - } - - if self.options.generate_block { - output_vector.push("--generate-block".into()); - } - - if self.options.block_extern_crate { - output_vector.push("--block-extern-crate".into()); - } - - if self.options.builtins { - output_vector.push("--builtins".into()); - } - - if let Some(ref prefix) = self.options.ctypes_prefix { - output_vector.push("--ctypes-prefix".into()); - output_vector.push(prefix.clone()); - } - - if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX { - output_vector.push("--anon-fields-prefix".into()); - output_vector.push(self.options.anon_fields_prefix.clone()); - } - - if self.options.emit_ast { - output_vector.push("--emit-clang-ast".into()); - } - - if self.options.emit_ir { - output_vector.push("--emit-ir".into()); - } - if let Some(ref graph) = self.options.emit_ir_graphviz { - output_vector.push("--emit-ir-graphviz".into()); - output_vector.push(graph.clone()) - } - if self.options.enable_cxx_namespaces { - output_vector.push("--enable-cxx-namespaces".into()); - } - if self.options.enable_function_attribute_detection { - output_vector.push("--enable-function-attribute-detection".into()); - } - if self.options.disable_name_namespacing { - output_vector.push("--disable-name-namespacing".into()); - } - if self.options.disable_nested_struct_naming { - output_vector.push("--disable-nested-struct-naming".into()); - } - - if self.options.disable_header_comment { - output_vector.push("--disable-header-comment".into()); - } - - if !self.options.codegen_config.functions() { - output_vector.push("--ignore-functions".into()); - } - - output_vector.push("--generate".into()); - - //Temporary placeholder for below 4 options - let mut options: Vec = Vec::new(); - if self.options.codegen_config.functions() { - options.push("functions".into()); - } - if self.options.codegen_config.types() { - options.push("types".into()); - } - if self.options.codegen_config.vars() { - options.push("vars".into()); - } - if self.options.codegen_config.methods() { - options.push("methods".into()); - } - if self.options.codegen_config.constructors() { - options.push("constructors".into()); - } - if self.options.codegen_config.destructors() { - options.push("destructors".into()); - } - - output_vector.push(options.join(",")); - - if !self.options.codegen_config.methods() { - output_vector.push("--ignore-methods".into()); - } - - if !self.options.convert_floats { - output_vector.push("--no-convert-floats".into()); - } - - if !self.options.prepend_enum_name { - output_vector.push("--no-prepend-enum-name".into()); - } - - if self.options.fit_macro_constants { - output_vector.push("--fit-macro-constant-types".into()); - } - - if self.options.array_pointers_in_arguments { - output_vector.push("--use-array-pointers-in-arguments".into()); - } - - if let Some(ref wasm_import_module_name) = - self.options.wasm_import_module_name - { - output_vector.push("--wasm-import-module-name".into()); - output_vector.push(wasm_import_module_name.clone()); - } - - for line in &self.options.raw_lines { - output_vector.push("--raw-line".into()); - output_vector.push(line.clone()); - } - - for (module, lines) in &self.options.module_lines { - for line in lines.iter() { - output_vector.push("--module-raw-line".into()); - output_vector.push(module.clone()); - output_vector.push(line.clone()); - } - } - - if self.options.use_core { - output_vector.push("--use-core".into()); - } - - if self.options.conservative_inline_namespaces { - output_vector.push("--conservative-inline-namespaces".into()); - } - - if self.options.generate_inline_functions { - output_vector.push("--generate-inline-functions".into()); - } - - if !self.options.record_matches { - output_vector.push("--no-record-matches".into()); - } - - if self.options.size_t_is_usize { - output_vector.push("--size_t-is-usize".into()); - } - - if !self.options.rustfmt_bindings { - output_vector.push("--no-rustfmt-bindings".into()); - } - - if let Some(path) = self - .options - .rustfmt_configuration_file - .as_ref() - .and_then(|f| f.to_str()) - { - output_vector.push("--rustfmt-configuration-file".into()); - output_vector.push(path.into()); - } - - if let Some(ref name) = self.options.dynamic_library_name { - output_vector.push("--dynamic-loading".into()); - output_vector.push(name.clone()); - } - - if self.options.dynamic_link_require_all { - output_vector.push("--dynamic-link-require-all".into()); - } - - if self.options.respect_cxx_access_specs { - output_vector.push("--respect-cxx-access-specs".into()); - } - - if self.options.translate_enum_integer_types { - output_vector.push("--translate-enum-integer-types".into()); - } - - if self.options.c_naming { - output_vector.push("--c-naming".into()); - } - - if self.options.force_explicit_padding { - output_vector.push("--explicit-padding".into()); - } - - if self.options.vtable_generation { - output_vector.push("--vtable-generation".into()); - } - - // Add clang arguments - - output_vector.push("--".into()); - - if !self.options.clang_args.is_empty() { - output_vector.extend(self.options.clang_args.iter().cloned()); - } - - if self.input_headers.len() > 1 { - // To pass more than one header, we need to pass all but the last - // header via the `-include` clang arg - for header in &self.input_headers[..self.input_headers.len() - 1] { - output_vector.push("-include".to_string()); - output_vector.push(header.clone()); - } - } - - output_vector - } - - /// Add an input C/C++ header to generate bindings for. - /// - /// This can be used to generate bindings to a single header: - /// - /// ```ignore - /// let bindings = bindgen::Builder::default() - /// .header("input.h") - /// .generate() - /// .unwrap(); - /// ``` - /// - /// Or you can invoke it multiple times to generate bindings to multiple - /// headers: - /// - /// ```ignore - /// let bindings = bindgen::Builder::default() - /// .header("first.h") - /// .header("second.h") - /// .header("third.h") - /// .generate() - /// .unwrap(); - /// ``` - pub fn header>(mut self, header: T) -> Builder { - self.input_headers.push(header.into()); - self - } - - /// Add a depfile output which will be written alongside the generated bindings. - pub fn depfile, D: Into>( - mut self, - output_module: H, - depfile: D, - ) -> Builder { - self.options.depfile = Some(deps::DepfileSpec { - output_module: output_module.into(), - depfile_path: depfile.into(), - }); - self - } - - /// Add `contents` as an input C/C++ header named `name`. - /// - /// The file `name` will be added to the clang arguments. - pub fn header_contents(mut self, name: &str, contents: &str) -> Builder { - // Apparently clang relies on having virtual FS correspondent to - // the real one, so we need absolute paths here - let absolute_path = env::current_dir() - .expect("Cannot retrieve current directory") - .join(name) - .to_str() - .expect("Cannot convert current directory name to string") - .to_owned(); - self.input_header_contents - .push((absolute_path, contents.into())); - self - } - - /// Specify the rust target - /// - /// The default is the latest stable Rust version - pub fn rust_target(mut self, rust_target: RustTarget) -> Self { - self.options.set_rust_target(rust_target); - self - } - - /// Disable support for native Rust unions, if supported. - pub fn disable_untagged_union(mut self) -> Self { - self.options.rust_features.untagged_union = false; - self - } - - /// Disable insertion of bindgen's version identifier into generated - /// bindings. - pub fn disable_header_comment(mut self) -> Self { - self.options.disable_header_comment = true; - self - } - - /// Set the output graphviz file. - pub fn emit_ir_graphviz>(mut self, path: T) -> Builder { - let path = path.into(); - self.options.emit_ir_graphviz = Some(path); - self - } - - /// Whether the generated bindings should contain documentation comments - /// (docstrings) or not. This is set to true by default. - /// - /// Note that clang by default excludes comments from system headers, pass - /// `-fretain-comments-from-system-headers` as - /// [`clang_arg`][Builder::clang_arg] to include them. It can also be told - /// to process all comments (not just documentation ones) using the - /// `-fparse-all-comments` flag. See [slides on clang comment parsing]( - /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for - /// background and examples. - pub fn generate_comments(mut self, doit: bool) -> Self { - self.options.generate_comments = doit; - self - } - - /// Whether to allowlist recursively or not. Defaults to true. - /// - /// Given that we have explicitly allowlisted the "initiate_dance_party" - /// function in this C header: - /// - /// ```c - /// typedef struct MoonBoots { - /// int bouncy_level; - /// } MoonBoots; - /// - /// void initiate_dance_party(MoonBoots* boots); - /// ``` - /// - /// We would normally generate bindings to both the `initiate_dance_party` - /// function and the `MoonBoots` struct that it transitively references. By - /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit - /// bindings for anything except the explicitly allowlisted items, and there - /// would be no emitted struct definition for `MoonBoots`. However, the - /// `initiate_dance_party` function would still reference `MoonBoots`! - /// - /// **Disabling this feature will almost certainly cause `bindgen` to emit - /// bindings that will not compile!** If you disable this feature, then it - /// is *your* responsibility to provide definitions for every type that is - /// referenced from an explicitly allowlisted item. One way to provide the - /// definitions is by using the [`Builder::raw_line`](#method.raw_line) - /// method, another would be to define them in Rust and then `include!(...)` - /// the bindings immediately afterwards. - pub fn allowlist_recursively(mut self, doit: bool) -> Self { - self.options.allowlist_recursively = doit; - self - } - - /// Deprecated alias for allowlist_recursively. - #[deprecated(note = "Use allowlist_recursively instead")] - pub fn whitelist_recursively(self, doit: bool) -> Self { - self.allowlist_recursively(doit) - } - - /// Generate `#[macro_use] extern crate objc;` instead of `use objc;` - /// in the prologue of the files generated from objective-c files - pub fn objc_extern_crate(mut self, doit: bool) -> Self { - self.options.objc_extern_crate = doit; - self - } - - /// Generate proper block signatures instead of void pointers. - pub fn generate_block(mut self, doit: bool) -> Self { - self.options.generate_block = doit; - self - } - - /// Generate `#[macro_use] extern crate block;` instead of `use block;` - /// in the prologue of the files generated from apple block files - pub fn block_extern_crate(mut self, doit: bool) -> Self { - self.options.block_extern_crate = doit; - self - } - - /// Whether to use the clang-provided name mangling. This is true by default - /// and probably needed for C++ features. - /// - /// However, some old libclang versions seem to return incorrect results in - /// some cases for non-mangled functions, see [1], so we allow disabling it. - /// - /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528 - pub fn trust_clang_mangling(mut self, doit: bool) -> Self { - self.options.enable_mangling = doit; - self - } - - /// Hide the given type from the generated bindings. Regular expressions are - /// supported. - #[deprecated(note = "Use blocklist_type instead")] - pub fn hide_type>(self, arg: T) -> Builder { - self.blocklist_type(arg) - } - - /// Hide the given type from the generated bindings. Regular expressions are - /// supported. - #[deprecated(note = "Use blocklist_type instead")] - pub fn blacklist_type>(self, arg: T) -> Builder { - self.blocklist_type(arg) - } - - /// Hide the given type from the generated bindings. Regular expressions are - /// supported. - /// - /// To blocklist types prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn blocklist_type>(mut self, arg: T) -> Builder { - self.options.blocklisted_types.insert(arg); - self - } - - /// Hide the given function from the generated bindings. Regular expressions - /// are supported. - #[deprecated(note = "Use blocklist_function instead")] - pub fn blacklist_function>(self, arg: T) -> Builder { - self.blocklist_function(arg) - } - - /// Hide the given function from the generated bindings. Regular expressions - /// are supported. - /// - /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn blocklist_function>(mut self, arg: T) -> Builder { - self.options.blocklisted_functions.insert(arg); - self - } - - /// Hide the given item from the generated bindings, regardless of - /// whether it's a type, function, module, etc. Regular - /// expressions are supported. - #[deprecated(note = "Use blocklist_item instead")] - pub fn blacklist_item>(mut self, arg: T) -> Builder { - self.options.blocklisted_items.insert(arg); - self - } - - /// Hide the given item from the generated bindings, regardless of - /// whether it's a type, function, module, etc. Regular - /// expressions are supported. - /// - /// To blocklist items prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn blocklist_item>(mut self, arg: T) -> Builder { - self.options.blocklisted_items.insert(arg); - self - } - - /// Hide any contents of the given file from the generated bindings, - /// regardless of whether it's a type, function, module etc. - pub fn blocklist_file>(mut self, arg: T) -> Builder { - self.options.blocklisted_files.insert(arg); - self - } - - /// Treat the given type as opaque in the generated bindings. Regular - /// expressions are supported. - /// - /// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn opaque_type>(mut self, arg: T) -> Builder { - self.options.opaque_types.insert(arg); - self - } - - /// Allowlist the given type so that it (and all types that it transitively - /// refers to) appears in the generated bindings. Regular expressions are - /// supported. - #[deprecated(note = "use allowlist_type instead")] - pub fn whitelisted_type>(self, arg: T) -> Builder { - self.allowlist_type(arg) - } - - /// Allowlist the given type so that it (and all types that it transitively - /// refers to) appears in the generated bindings. Regular expressions are - /// supported. - #[deprecated(note = "use allowlist_type instead")] - pub fn whitelist_type>(self, arg: T) -> Builder { - self.allowlist_type(arg) - } - - /// Allowlist the given type so that it (and all types that it transitively - /// refers to) appears in the generated bindings. Regular expressions are - /// supported. - /// - /// To allowlist types prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn allowlist_type>(mut self, arg: T) -> Builder { - self.options.allowlisted_types.insert(arg); - self - } - - /// Allowlist the given function so that it (and all types that it - /// transitively refers to) appears in the generated bindings. Regular - /// expressions are supported. - /// - /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn allowlist_function>(mut self, arg: T) -> Builder { - self.options.allowlisted_functions.insert(arg); - self - } - - /// Allowlist the given function. - /// - /// Deprecated: use allowlist_function instead. - #[deprecated(note = "use allowlist_function instead")] - pub fn whitelist_function>(self, arg: T) -> Builder { - self.allowlist_function(arg) - } - - /// Allowlist the given function. - /// - /// Deprecated: use allowlist_function instead. - #[deprecated(note = "use allowlist_function instead")] - pub fn whitelisted_function>(self, arg: T) -> Builder { - self.allowlist_function(arg) - } - - /// Allowlist the given variable so that it (and all types that it - /// transitively refers to) appears in the generated bindings. Regular - /// expressions are supported. - /// - /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`. - /// For more complicated expressions check - /// [regex](https://docs.rs/regex/*/regex/) docs - pub fn allowlist_var>(mut self, arg: T) -> Builder { - self.options.allowlisted_vars.insert(arg); - self - } - - /// Allowlist the given file so that its contents appear in the generated bindings. - pub fn allowlist_file>(mut self, arg: T) -> Builder { - self.options.allowlisted_files.insert(arg); - self - } - - /// Deprecated: use allowlist_var instead. - #[deprecated(note = "use allowlist_var instead")] - pub fn whitelist_var>(self, arg: T) -> Builder { - self.allowlist_var(arg) - } - - /// Allowlist the given variable. - /// - /// Deprecated: use allowlist_var instead. - #[deprecated(note = "use allowlist_var instead")] - pub fn whitelisted_var>(self, arg: T) -> Builder { - self.allowlist_var(arg) - } - - /// Set the default style of code to generate for enums - pub fn default_enum_style( - mut self, - arg: codegen::EnumVariation, - ) -> Builder { - self.options.default_enum_style = arg; - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as being - /// bitfield-like. Regular expressions are supported. - /// - /// This makes bindgen generate a type that isn't a rust `enum`. Regular - /// expressions are supported. - /// - /// This is similar to the newtype enum style, but with the bitwise - /// operators implemented. - pub fn bitfield_enum>(mut self, arg: T) -> Builder { - self.options.bitfield_enums.insert(arg); - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as a newtype. - /// Regular expressions are supported. - /// - /// This makes bindgen generate a type that isn't a Rust `enum`. Regular - /// expressions are supported. - pub fn newtype_enum>(mut self, arg: T) -> Builder { - self.options.newtype_enums.insert(arg); - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as a Rust - /// enum. - /// - /// This makes bindgen generate enums instead of constants. Regular - /// expressions are supported. - /// - /// **Use this with caution**, creating this in unsafe code - /// (including FFI) with an invalid value will invoke undefined behaviour. - /// You may want to use the newtype enum style instead. - pub fn rustified_enum>(mut self, arg: T) -> Builder { - self.options.rustified_enums.insert(arg); - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as a Rust - /// enum with the `#[non_exhaustive]` attribute. - /// - /// This makes bindgen generate enums instead of constants. Regular - /// expressions are supported. - /// - /// **Use this with caution**, creating this in unsafe code - /// (including FFI) with an invalid value will invoke undefined behaviour. - /// You may want to use the newtype enum style instead. - pub fn rustified_non_exhaustive_enum>( - mut self, - arg: T, - ) -> Builder { - self.options.rustified_non_exhaustive_enums.insert(arg); - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as a set of - /// constants that are not to be put into a module. - pub fn constified_enum>(mut self, arg: T) -> Builder { - self.options.constified_enums.insert(arg); - self - } - - /// Mark the given enum (or set of enums, if using a pattern) as a set of - /// constants that should be put into a module. - /// - /// This makes bindgen generate modules containing constants instead of - /// just constants. Regular expressions are supported. - pub fn constified_enum_module>(mut self, arg: T) -> Builder { - self.options.constified_enum_modules.insert(arg); - self - } - - /// Set the default type for macro constants - pub fn default_macro_constant_type( - mut self, - arg: codegen::MacroTypeVariation, - ) -> Builder { - self.options.default_macro_constant_type = arg; - self - } - - /// Set the default style of code to generate for typedefs - pub fn default_alias_style( - mut self, - arg: codegen::AliasVariation, - ) -> Builder { - self.options.default_alias_style = arg; - self - } - - /// Mark the given typedef alias (or set of aliases, if using a pattern) to - /// use regular Rust type aliasing. - /// - /// This is the default behavior and should be used if `default_alias_style` - /// was set to NewType or NewTypeDeref and you want to override it for a - /// set of typedefs. - pub fn type_alias>(mut self, arg: T) -> Builder { - self.options.type_alias.insert(arg); - self - } - - /// Mark the given typedef alias (or set of aliases, if using a pattern) to - /// be generated as a new type by having the aliased type be wrapped in a - /// #[repr(transparent)] struct. - /// - /// Used to enforce stricter type checking. - pub fn new_type_alias>(mut self, arg: T) -> Builder { - self.options.new_type_alias.insert(arg); - self - } - - /// Mark the given typedef alias (or set of aliases, if using a pattern) to - /// be generated as a new type by having the aliased type be wrapped in a - /// #[repr(transparent)] struct and also have an automatically generated - /// impl's of `Deref` and `DerefMut` to their aliased type. - pub fn new_type_alias_deref>(mut self, arg: T) -> Builder { - self.options.new_type_alias_deref.insert(arg); - self - } - - /// Add a string to prepend to the generated bindings. The string is passed - /// through without any modification. - pub fn raw_line>(mut self, arg: T) -> Self { - self.options.raw_lines.push(arg.into()); - self - } - - /// Add a given line to the beginning of module `mod`. - pub fn module_raw_line(mut self, mod_: T, line: U) -> Self - where - T: Into, - U: Into, - { - self.options - .module_lines - .entry(mod_.into()) - .or_insert_with(Vec::new) - .push(line.into()); - self - } - - /// Add a given set of lines to the beginning of module `mod`. - pub fn module_raw_lines(mut self, mod_: T, lines: I) -> Self - where - T: Into, - I: IntoIterator, - I::Item: Into, - { - self.options - .module_lines - .entry(mod_.into()) - .or_insert_with(Vec::new) - .extend(lines.into_iter().map(Into::into)); - self - } - - /// Add an argument to be passed straight through to clang. - pub fn clang_arg>(mut self, arg: T) -> Builder { - self.options.clang_args.push(arg.into()); - self - } - - /// Add arguments to be passed straight through to clang. - pub fn clang_args(mut self, iter: I) -> Builder - where - I: IntoIterator, - I::Item: AsRef, - { - for arg in iter { - self = self.clang_arg(arg.as_ref()) - } - self - } - - /// Emit bindings for builtin definitions (for example `__builtin_va_list`) - /// in the generated Rust. - pub fn emit_builtins(mut self) -> Builder { - self.options.builtins = true; - self - } - - /// Avoid converting floats to `f32`/`f64` by default. - pub fn no_convert_floats(mut self) -> Self { - self.options.convert_floats = false; - self - } - - /// Set whether layout tests should be generated. - pub fn layout_tests(mut self, doit: bool) -> Self { - self.options.layout_tests = doit; - self - } - - /// Set whether `Debug` should be implemented, if it can not be derived automatically. - pub fn impl_debug(mut self, doit: bool) -> Self { - self.options.impl_debug = doit; - self - } - - /// Set whether `PartialEq` should be implemented, if it can not be derived automatically. - pub fn impl_partialeq(mut self, doit: bool) -> Self { - self.options.impl_partialeq = doit; - self - } - - /// Set whether `Copy` should be derived by default. - pub fn derive_copy(mut self, doit: bool) -> Self { - self.options.derive_copy = doit; - self - } - - /// Set whether `Debug` should be derived by default. - pub fn derive_debug(mut self, doit: bool) -> Self { - self.options.derive_debug = doit; - self - } - - /// Set whether `Default` should be derived by default. - pub fn derive_default(mut self, doit: bool) -> Self { - self.options.derive_default = doit; - self - } - - /// Set whether `Hash` should be derived by default. - pub fn derive_hash(mut self, doit: bool) -> Self { - self.options.derive_hash = doit; - self - } - - /// Set whether `PartialOrd` should be derived by default. - /// If we don't compute partialord, we also cannot compute - /// ord. Set the derive_ord to `false` when doit is `false`. - pub fn derive_partialord(mut self, doit: bool) -> Self { - self.options.derive_partialord = doit; - if !doit { - self.options.derive_ord = false; - } - self - } - - /// Set whether `Ord` should be derived by default. - /// We can't compute `Ord` without computing `PartialOrd`, - /// so we set the same option to derive_partialord. - pub fn derive_ord(mut self, doit: bool) -> Self { - self.options.derive_ord = doit; - self.options.derive_partialord = doit; - self - } - - /// Set whether `PartialEq` should be derived by default. - /// - /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving - /// `Eq` is also disabled when `doit` is `false`. - pub fn derive_partialeq(mut self, doit: bool) -> Self { - self.options.derive_partialeq = doit; - if !doit { - self.options.derive_eq = false; - } - self - } - - /// Set whether `Eq` should be derived by default. - /// - /// We can't derive `Eq` without also deriving `PartialEq`, so we also - /// enable deriving `PartialEq` when `doit` is `true`. - pub fn derive_eq(mut self, doit: bool) -> Self { - self.options.derive_eq = doit; - if doit { - self.options.derive_partialeq = doit; - } - self - } - - /// Set whether or not to time bindgen phases, and print information to - /// stderr. - pub fn time_phases(mut self, doit: bool) -> Self { - self.options.time_phases = doit; - self - } - - /// Emit Clang AST. - pub fn emit_clang_ast(mut self) -> Builder { - self.options.emit_ast = true; - self - } - - /// Emit IR. - pub fn emit_ir(mut self) -> Builder { - self.options.emit_ir = true; - self - } - - /// Enable C++ namespaces. - pub fn enable_cxx_namespaces(mut self) -> Builder { - self.options.enable_cxx_namespaces = true; - self - } - - /// Enable detecting must_use attributes on C functions. - /// - /// This is quite slow in some cases (see #1465), so it's disabled by - /// default. - /// - /// Note that for this to do something meaningful for now at least, the rust - /// target version has to have support for `#[must_use]`. - pub fn enable_function_attribute_detection(mut self) -> Self { - self.options.enable_function_attribute_detection = true; - self - } - - /// Disable name auto-namespacing. - /// - /// By default, bindgen mangles names like `foo::bar::Baz` to look like - /// `foo_bar_Baz` instead of just `Baz`. - /// - /// This method disables that behavior. - /// - /// Note that this intentionally does not change the names used for - /// allowlisting and blocklisting, which should still be mangled with the - /// namespaces. - /// - /// Note, also, that this option may cause bindgen to generate duplicate - /// names. - pub fn disable_name_namespacing(mut self) -> Builder { - self.options.disable_name_namespacing = true; - self - } - - /// Disable nested struct naming. - /// - /// The following structs have different names for C and C++. In case of C - /// they are visible as `foo` and `bar`. In case of C++ they are visible as - /// `foo` and `foo::bar`. - /// - /// ```c - /// struct foo { - /// struct bar { - /// } b; - /// }; - /// ``` - /// - /// Bindgen wants to avoid duplicate names by default so it follows C++ naming - /// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`. - /// - /// This method disables this behavior and it is indented to be used only - /// for headers that were written for C. - pub fn disable_nested_struct_naming(mut self) -> Builder { - self.options.disable_nested_struct_naming = true; - self - } - - /// Treat inline namespaces conservatively. - /// - /// This is tricky, because in C++ is technically legal to override an item - /// defined in an inline namespace: - /// - /// ```cpp - /// inline namespace foo { - /// using Bar = int; - /// } - /// using Bar = long; - /// ``` - /// - /// Even though referencing `Bar` is a compiler error. - /// - /// We want to support this (arguably esoteric) use case, but we don't want - /// to make the rest of bindgen users pay an usability penalty for that. - /// - /// To support this, we need to keep all the inline namespaces around, but - /// then bindgen usage is a bit more difficult, because you cannot - /// reference, e.g., `std::string` (you'd need to use the proper inline - /// namespace). - /// - /// We could complicate a lot of the logic to detect name collisions, and if - /// not detected generate a `pub use inline_ns::*` or something like that. - /// - /// That's probably something we can do if we see this option is needed in a - /// lot of cases, to improve it's usability, but my guess is that this is - /// not going to be too useful. - pub fn conservative_inline_namespaces(mut self) -> Builder { - self.options.conservative_inline_namespaces = true; - self - } - - /// Whether inline functions should be generated or not. - /// - /// 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. - pub fn generate_inline_functions(mut self, doit: bool) -> Self { - self.options.generate_inline_functions = doit; - self - } - - /// Ignore functions. - pub fn ignore_functions(mut self) -> Builder { - self.options.codegen_config.remove(CodegenConfig::FUNCTIONS); - self - } - - /// Ignore methods. - pub fn ignore_methods(mut self) -> Builder { - self.options.codegen_config.remove(CodegenConfig::METHODS); - self - } - - /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings. - #[deprecated(note = "please use `rust_target` instead")] - pub fn unstable_rust(self, doit: bool) -> Self { - let rust_target = if doit { - RustTarget::Nightly - } else { - LATEST_STABLE_RUST - }; - self.rust_target(rust_target) - } - - /// Use core instead of libstd in the generated bindings. - pub fn use_core(mut self) -> Builder { - self.options.use_core = true; - self - } - - /// Use the given prefix for the raw types instead of `::std::os::raw`. - pub fn ctypes_prefix>(mut self, prefix: T) -> Builder { - self.options.ctypes_prefix = Some(prefix.into()); - self - } - - /// Use the given prefix for the anon fields. - pub fn anon_fields_prefix>(mut self, prefix: T) -> Builder { - self.options.anon_fields_prefix = prefix.into(); - self - } - - /// Allows configuring types in different situations, see the - /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation. - pub fn parse_callbacks( - mut self, - cb: Box, - ) -> Self { - self.options.parse_callbacks = Some(cb); - self - } - - /// Choose what to generate using a - /// [`CodegenConfig`](./struct.CodegenConfig.html). - pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self { - self.options.codegen_config = config; - self - } - - /// Whether to detect include paths using clang_sys. - pub fn detect_include_paths(mut self, doit: bool) -> Self { - self.options.detect_include_paths = doit; - self - } - - /// Whether to try to fit macro constants to types smaller than u32/i32 - pub fn fit_macro_constants(mut self, doit: bool) -> Self { - self.options.fit_macro_constants = doit; - self - } - - /// Prepend the enum name to constant or newtype variants. - pub fn prepend_enum_name(mut self, doit: bool) -> Self { - self.options.prepend_enum_name = doit; - self - } - - /// Set whether `size_t` should be translated to `usize` automatically. - pub fn size_t_is_usize(mut self, is: bool) -> Self { - self.options.size_t_is_usize = is; - self - } - - /// Set whether rustfmt should format the generated bindings. - pub fn rustfmt_bindings(mut self, doit: bool) -> Self { - self.options.rustfmt_bindings = doit; - self - } - - /// Set whether we should record matched items in our regex sets. - pub fn record_matches(mut self, doit: bool) -> Self { - self.options.record_matches = doit; - self - } - - /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt - /// options are used. - pub fn rustfmt_configuration_file(mut self, path: Option) -> Self { - self = self.rustfmt_bindings(true); - self.options.rustfmt_configuration_file = path; - self - } - - /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled. - pub fn with_rustfmt>(mut self, path: P) -> Self { - self.options.rustfmt_path = Some(path.into()); - self - } - - /// If true, always emit explicit padding fields. - /// - /// If a struct needs to be serialized in its native format (padding bytes - /// and all), for example writing it to a file or sending it on the network, - /// then this should be enabled, as anything reading the padding bytes of - /// a struct may lead to Undefined Behavior. - pub fn explicit_padding(mut self, doit: bool) -> Self { - self.options.force_explicit_padding = doit; - self - } - - /// If true, enables experimental support to generate vtable functions. - /// - /// Should mostly work, though some edge cases are likely to be broken. - pub fn vtable_generation(mut self, doit: bool) -> Self { - self.options.vtable_generation = doit; - self - } - - /// Generate the Rust bindings using the options built up thus far. - pub fn generate(mut self) -> Result { - // Add any extra arguments from the environment to the clang command line. - self.options.clang_args.extend(get_extra_clang_args()); - - // Transform input headers to arguments on the clang command line. - self.options.input_header = self.input_headers.pop(); - self.options.extra_input_headers = self.input_headers; - self.options.clang_args.extend( - self.options.extra_input_headers.iter().flat_map(|header| { - iter::once("-include".into()) - .chain(iter::once(header.to_string())) - }), - ); - - self.options.input_unsaved_files.extend( - self.input_header_contents - .drain(..) - .map(|(name, contents)| { - clang::UnsavedFile::new(&name, &contents) - }), - ); - - Bindings::generate(self.options) - } - - /// Preprocess and dump the input header files to disk. - /// - /// This is useful when debugging bindgen, using C-Reduce, or when filing - /// issues. The resulting file will be named something like `__bindgen.i` or - /// `__bindgen.ii` - pub fn dump_preprocessed_input(&self) -> io::Result<()> { - let clang = - clang_sys::support::Clang::find(None, &[]).ok_or_else(|| { - io::Error::new( - io::ErrorKind::Other, - "Cannot find clang executable", - ) - })?; - - // The contents of a wrapper file that includes all the input header - // files. - let mut wrapper_contents = String::new(); - - // Whether we are working with C or C++ inputs. - let mut is_cpp = args_are_cpp(&self.options.clang_args); - - // For each input header, add `#include "$header"`. - for header in &self.input_headers { - is_cpp |= file_is_cpp(header); - - wrapper_contents.push_str("#include \""); - wrapper_contents.push_str(header); - wrapper_contents.push_str("\"\n"); - } - - // For each input header content, add a prefix line of `#line 0 "$name"` - // followed by the contents. - for &(ref name, ref contents) in &self.input_header_contents { - is_cpp |= file_is_cpp(name); - - wrapper_contents.push_str("#line 0 \""); - wrapper_contents.push_str(name); - wrapper_contents.push_str("\"\n"); - wrapper_contents.push_str(contents); - } - - let wrapper_path = PathBuf::from(if is_cpp { - "__bindgen.cpp" - } else { - "__bindgen.c" - }); - - { - let mut wrapper_file = File::create(&wrapper_path)?; - wrapper_file.write_all(wrapper_contents.as_bytes())?; - } - - let mut cmd = Command::new(&clang.path); - cmd.arg("-save-temps") - .arg("-E") - .arg("-C") - .arg("-c") - .arg(&wrapper_path) - .stdout(Stdio::piped()); - - for a in &self.options.clang_args { - cmd.arg(a); - } - - for a in get_extra_clang_args() { - cmd.arg(a); - } - - let mut child = cmd.spawn()?; - - let mut preprocessed = child.stdout.take().unwrap(); - let mut file = File::create(if is_cpp { - "__bindgen.ii" - } else { - "__bindgen.i" - })?; - io::copy(&mut preprocessed, &mut file)?; - - if child.wait()?.success() { - Ok(()) - } else { - Err(io::Error::new( - io::ErrorKind::Other, - "clang exited with non-zero status", - )) - } - } - - /// Don't derive `PartialEq` for a given type. Regular - /// expressions are supported. - pub fn no_partialeq>(mut self, arg: T) -> Builder { - self.options.no_partialeq_types.insert(arg.into()); - self - } - - /// Don't derive `Copy` for a given type. Regular - /// expressions are supported. - pub fn no_copy>(mut self, arg: T) -> Self { - self.options.no_copy_types.insert(arg.into()); - self - } - - /// Don't derive `Debug` for a given type. Regular - /// expressions are supported. - pub fn no_debug>(mut self, arg: T) -> Self { - self.options.no_debug_types.insert(arg.into()); - self - } - - /// Don't derive/impl `Default` for a given type. Regular - /// expressions are supported. - pub fn no_default>(mut self, arg: T) -> Self { - self.options.no_default_types.insert(arg.into()); - self - } - - /// Don't derive `Hash` for a given type. Regular - /// expressions are supported. - pub fn no_hash>(mut self, arg: T) -> Builder { - self.options.no_hash_types.insert(arg.into()); - self - } - - /// Add `#[must_use]` for the given type. Regular - /// expressions are supported. - pub fn must_use_type>(mut self, arg: T) -> Builder { - self.options.must_use_types.insert(arg.into()); - self - } - - /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut) - pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { - self.options.array_pointers_in_arguments = doit; - self - } - - /// Set the wasm import module name - pub fn wasm_import_module_name>( - mut self, - import_name: T, - ) -> Self { - self.options.wasm_import_module_name = Some(import_name.into()); - self - } - - /// Specify the dynamic library name if we are generating bindings for a shared library. - pub fn dynamic_library_name>( - mut self, - dynamic_library_name: T, - ) -> Self { - self.options.dynamic_library_name = Some(dynamic_library_name.into()); - self - } - - /// Require successful linkage for all routines in a shared library. - /// This allows us to optimize function calls by being able to safely assume function pointers - /// are valid. - pub fn dynamic_link_require_all(mut self, req: bool) -> Self { - self.options.dynamic_link_require_all = req; - self - } - - /// Generate bindings as `pub` only if the bound item is publically accessible by C++. - pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self { - self.options.respect_cxx_access_specs = doit; - self - } - - /// Always translate enum integer types to native Rust integer types. - /// - /// This will result in enums having types such as `u32` and `i16` instead - /// of `c_uint` and `c_short`. Types for Rustified enums are always - /// translated. - pub fn translate_enum_integer_types(mut self, doit: bool) -> Self { - self.options.translate_enum_integer_types = doit; - self - } - - /// Generate types with C style naming. - /// - /// This will add prefixes to the generated type names. For example instead of a struct `A` we - /// will generate struct `struct_A`. Currently applies to structs, unions, and enums. - pub fn c_naming(mut self, doit: bool) -> Self { - self.options.c_naming = doit; - self - } -} - -/// Configuration options for generated bindings. -#[derive(Debug)] -struct BindgenOptions { - /// The set of types that have been blocklisted and should not appear - /// anywhere in the generated code. - blocklisted_types: RegexSet, - - /// The set of functions that have been blocklisted and should not appear - /// in the generated code. - blocklisted_functions: RegexSet, - - /// The set of items, regardless of item-type, that have been - /// blocklisted and should not appear in the generated code. - blocklisted_items: RegexSet, - - /// The set of files whose contents should be blocklisted and should not - /// appear in the generated code. - blocklisted_files: RegexSet, - - /// The set of types that should be treated as opaque structures in the - /// generated code. - opaque_types: RegexSet, - - /// The explicit rustfmt path. - rustfmt_path: Option, - - /// The path to which we should write a Makefile-syntax depfile (if any). - depfile: Option, - - /// The set of types that we should have bindings for in the generated - /// code. - /// - /// This includes all types transitively reachable from any type in this - /// set. One might think of allowlisted types/vars/functions as GC roots, - /// and the generated Rust code as including everything that gets marked. - allowlisted_types: RegexSet, - - /// Allowlisted functions. See docs for `allowlisted_types` for more. - allowlisted_functions: RegexSet, - - /// Allowlisted variables. See docs for `allowlisted_types` for more. - allowlisted_vars: RegexSet, - - /// The set of files whose contents should be allowlisted. - allowlisted_files: RegexSet, - - /// The default style of code to generate for enums - default_enum_style: codegen::EnumVariation, - - /// The enum patterns to mark an enum as a bitfield - /// (newtype with bitwise operations). - bitfield_enums: RegexSet, - - /// The enum patterns to mark an enum as a newtype. - newtype_enums: RegexSet, - - /// The enum patterns to mark an enum as a Rust enum. - rustified_enums: RegexSet, - - /// The enum patterns to mark an enum as a non-exhaustive Rust enum. - rustified_non_exhaustive_enums: RegexSet, - - /// The enum patterns to mark an enum as a module of constants. - constified_enum_modules: RegexSet, - - /// The enum patterns to mark an enum as a set of constants. - constified_enums: RegexSet, - - /// The default type for C macro constants. - default_macro_constant_type: codegen::MacroTypeVariation, - - /// The default style of code to generate for typedefs. - default_alias_style: codegen::AliasVariation, - - /// Typedef patterns that will use regular type aliasing. - type_alias: RegexSet, - - /// Typedef patterns that will be aliased by creating a new struct. - new_type_alias: RegexSet, - - /// Typedef patterns that will be wrapped in a new struct and have - /// Deref and Deref to their aliased type. - new_type_alias_deref: RegexSet, - - /// Whether we should generate builtins or not. - builtins: bool, - - /// True if we should dump the Clang AST for debugging purposes. - emit_ast: bool, - - /// True if we should dump our internal IR for debugging purposes. - emit_ir: bool, - - /// Output graphviz dot file. - emit_ir_graphviz: Option, - - /// True if we should emulate C++ namespaces with Rust modules in the - /// generated bindings. - enable_cxx_namespaces: bool, - - /// True if we should try to find unexposed attributes in functions, in - /// order to be able to generate #[must_use] attributes in Rust. - enable_function_attribute_detection: bool, - - /// True if we should avoid mangling names with namespaces. - disable_name_namespacing: bool, - - /// True if we should avoid generating nested struct names. - disable_nested_struct_naming: bool, - - /// True if we should avoid embedding version identifiers into source code. - disable_header_comment: bool, - - /// True if we should generate layout tests for generated structures. - layout_tests: bool, - - /// True if we should implement the Debug trait for C/C++ structures and types - /// that do not support automatically deriving Debug. - impl_debug: bool, - - /// True if we should implement the PartialEq trait for C/C++ structures and types - /// that do not support automatically deriving PartialEq. - impl_partialeq: bool, - - /// True if we should derive Copy trait implementations for C/C++ structures - /// and types. - derive_copy: bool, - - /// True if we should derive Debug trait implementations for C/C++ structures - /// and types. - derive_debug: bool, - - /// True if we should derive Default trait implementations for C/C++ structures - /// and types. - derive_default: bool, - - /// True if we should derive Hash trait implementations for C/C++ structures - /// and types. - derive_hash: bool, - - /// True if we should derive PartialOrd trait implementations for C/C++ structures - /// and types. - derive_partialord: bool, - - /// True if we should derive Ord trait implementations for C/C++ structures - /// and types. - derive_ord: bool, - - /// True if we should derive PartialEq trait implementations for C/C++ structures - /// and types. - derive_partialeq: bool, - - /// True if we should derive Eq trait implementations for C/C++ structures - /// and types. - derive_eq: bool, - - /// True if we should avoid using libstd to use libcore instead. - use_core: bool, - - /// An optional prefix for the "raw" types, like `c_int`, `c_void`... - ctypes_prefix: Option, - - /// The prefix for the anon fields. - anon_fields_prefix: String, - - /// Whether to time the bindgen phases. - time_phases: bool, - - /// Whether we should convert float types to f32/f64 types. - convert_floats: bool, - - /// The set of raw lines to prepend to the top-level module of generated - /// Rust code. - raw_lines: Vec, - - /// The set of raw lines to prepend to each of the modules. - /// - /// This only makes sense if the `enable_cxx_namespaces` option is set. - module_lines: HashMap>, - - /// The set of arguments to pass straight through to Clang. - clang_args: Vec, - - /// The input header file. - input_header: Option, - - /// Any additional input header files. - extra_input_headers: Vec, - - /// Unsaved files for input. - input_unsaved_files: Vec, - - /// A user-provided visitor to allow customizing different kinds of - /// situations. - parse_callbacks: Option>, - - /// Which kind of items should we generate? By default, we'll generate all - /// of them. - codegen_config: CodegenConfig, - - /// Whether to treat inline namespaces conservatively. - /// - /// See the builder method description for more details. - conservative_inline_namespaces: bool, - - /// Whether to keep documentation comments in the generated output. See the - /// documentation for more details. Defaults to true. - generate_comments: bool, - - /// Whether to generate inline functions. Defaults to false. - generate_inline_functions: bool, - - /// Whether to allowlist types recursively. Defaults to true. - allowlist_recursively: bool, - - /// Instead of emitting 'use objc;' to files generated from objective c files, - /// generate '#[macro_use] extern crate objc;' - objc_extern_crate: bool, - - /// Instead of emitting 'use block;' to files generated from objective c files, - /// generate '#[macro_use] extern crate block;' - generate_block: bool, - - /// Instead of emitting 'use block;' to files generated from objective c files, - /// generate '#[macro_use] extern crate block;' - block_extern_crate: bool, - - /// Whether to use the clang-provided name mangling. This is true and - /// probably needed for C++ features. - /// - /// However, some old libclang versions seem to return incorrect results in - /// some cases for non-mangled functions, see [1], so we allow disabling it. - /// - /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528 - enable_mangling: bool, - - /// Whether to detect include paths using clang_sys. - detect_include_paths: bool, - - /// Whether to try to fit macro constants into types smaller than u32/i32 - fit_macro_constants: bool, - - /// Whether to prepend the enum name to constant or newtype variants. - prepend_enum_name: bool, - - /// Version of the Rust compiler to target - rust_target: RustTarget, - - /// Features to enable, derived from `rust_target` - rust_features: RustFeatures, - - /// Whether we should record which items in the regex sets ever matched. - /// - /// This may be a bit slower, but will enable reporting of unused allowlist - /// items via the `error!` log. - record_matches: bool, - - /// Whether `size_t` should be translated to `usize` automatically. - size_t_is_usize: bool, - - /// Whether rustfmt should format the generated bindings. - rustfmt_bindings: bool, - - /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt - /// options are used. - rustfmt_configuration_file: Option, - - /// The set of types that we should not derive `PartialEq` for. - no_partialeq_types: RegexSet, - - /// The set of types that we should not derive `Copy` for. - no_copy_types: RegexSet, - - /// The set of types that we should not derive `Debug` for. - no_debug_types: RegexSet, - - /// The set of types that we should not derive/impl `Default` for. - no_default_types: RegexSet, - - /// The set of types that we should not derive `Hash` for. - no_hash_types: RegexSet, - - /// The set of types that we should be annotated with `#[must_use]`. - must_use_types: RegexSet, - - /// Decide if C arrays should be regular pointers in rust or array pointers - array_pointers_in_arguments: bool, - - /// Wasm import module name. - wasm_import_module_name: Option, - - /// The name of the dynamic library (if we are generating bindings for a shared library). If - /// this is None, no dynamic bindings are created. - dynamic_library_name: Option, - - /// Require successful linkage for all routines in a shared library. - /// This allows us to optimize function calls by being able to safely assume function pointers - /// are valid. No effect if `dynamic_library_name` is None. - dynamic_link_require_all: bool, - - /// Only make generated bindings `pub` if the items would be publically accessible - /// by C++. - respect_cxx_access_specs: bool, - - /// Always translate enum integer types to native Rust integer types. - translate_enum_integer_types: bool, - - /// Generate types with C style naming. - c_naming: bool, - - /// Always output explicit padding fields - force_explicit_padding: bool, - - /// Emit vtable functions. - vtable_generation: bool, -} - -/// TODO(emilio): This is sort of a lie (see the error message that results from -/// removing this), but since we don't share references across panic boundaries -/// it's ok. -impl ::std::panic::UnwindSafe for BindgenOptions {} - -impl BindgenOptions { - fn build(&mut self) { - let mut regex_sets = [ - &mut self.allowlisted_vars, - &mut self.allowlisted_types, - &mut self.allowlisted_functions, - &mut self.allowlisted_files, - &mut self.blocklisted_types, - &mut self.blocklisted_functions, - &mut self.blocklisted_items, - &mut self.blocklisted_files, - &mut self.opaque_types, - &mut self.bitfield_enums, - &mut self.constified_enums, - &mut self.constified_enum_modules, - &mut self.newtype_enums, - &mut self.rustified_enums, - &mut self.rustified_non_exhaustive_enums, - &mut self.type_alias, - &mut self.new_type_alias, - &mut self.new_type_alias_deref, - &mut self.no_partialeq_types, - &mut self.no_copy_types, - &mut self.no_debug_types, - &mut self.no_default_types, - &mut self.no_hash_types, - &mut self.must_use_types, - ]; - let record_matches = self.record_matches; - for regex_set in &mut regex_sets { - regex_set.build(record_matches); - } - } - - /// 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 - pub fn rust_features(&self) -> RustFeatures { - self.rust_features - } -} - -impl Default for BindgenOptions { - fn default() -> BindgenOptions { - let rust_target = RustTarget::default(); - - BindgenOptions { - rust_target, - rust_features: rust_target.into(), - blocklisted_types: Default::default(), - blocklisted_functions: Default::default(), - blocklisted_items: Default::default(), - blocklisted_files: Default::default(), - opaque_types: Default::default(), - rustfmt_path: Default::default(), - depfile: Default::default(), - allowlisted_types: Default::default(), - allowlisted_functions: Default::default(), - allowlisted_vars: Default::default(), - allowlisted_files: Default::default(), - default_enum_style: Default::default(), - bitfield_enums: Default::default(), - newtype_enums: Default::default(), - rustified_enums: Default::default(), - rustified_non_exhaustive_enums: Default::default(), - constified_enums: Default::default(), - constified_enum_modules: Default::default(), - default_macro_constant_type: Default::default(), - default_alias_style: Default::default(), - type_alias: Default::default(), - new_type_alias: Default::default(), - new_type_alias_deref: Default::default(), - builtins: false, - emit_ast: false, - emit_ir: false, - emit_ir_graphviz: None, - layout_tests: true, - impl_debug: false, - impl_partialeq: false, - derive_copy: true, - derive_debug: true, - derive_default: false, - derive_hash: false, - derive_partialord: false, - derive_ord: false, - derive_partialeq: false, - derive_eq: false, - enable_cxx_namespaces: false, - enable_function_attribute_detection: false, - disable_name_namespacing: false, - disable_nested_struct_naming: false, - disable_header_comment: false, - use_core: false, - ctypes_prefix: None, - anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(), - convert_floats: true, - raw_lines: vec![], - module_lines: HashMap::default(), - clang_args: vec![], - input_header: None, - extra_input_headers: vec![], - input_unsaved_files: vec![], - parse_callbacks: None, - codegen_config: CodegenConfig::all(), - conservative_inline_namespaces: false, - generate_comments: true, - generate_inline_functions: false, - allowlist_recursively: true, - generate_block: false, - objc_extern_crate: false, - block_extern_crate: false, - enable_mangling: true, - detect_include_paths: true, - fit_macro_constants: false, - prepend_enum_name: true, - time_phases: false, - record_matches: true, - rustfmt_bindings: true, - size_t_is_usize: false, - rustfmt_configuration_file: None, - no_partialeq_types: Default::default(), - no_copy_types: Default::default(), - no_debug_types: Default::default(), - no_default_types: Default::default(), - no_hash_types: Default::default(), - must_use_types: Default::default(), - array_pointers_in_arguments: false, - wasm_import_module_name: None, - dynamic_library_name: None, - dynamic_link_require_all: false, - respect_cxx_access_specs: false, - translate_enum_integer_types: false, - c_naming: false, - force_explicit_padding: false, - vtable_generation: false, - } - } -} - -#[cfg(feature = "runtime")] -fn ensure_libclang_is_loaded() { - if clang_sys::is_loaded() { - return; - } - - // XXX (issue #350): Ensure that our dynamically loaded `libclang` - // doesn't get dropped prematurely, nor is loaded multiple times - // across different threads. - - lazy_static! { - static ref LIBCLANG: std::sync::Arc = { - clang_sys::load().expect("Unable to find libclang"); - clang_sys::get_library().expect( - "We just loaded libclang and it had better still be \ - here!", - ) - }; - } - - clang_sys::set_library(Some(LIBCLANG.clone())); -} - -#[cfg(not(feature = "runtime"))] -fn ensure_libclang_is_loaded() {} - -/// Error type for rust-bindgen. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum BindgenError { - /// The header was a folder. - FolderAsHeader(PathBuf), - /// Permissions to read the header is insufficient. - InsufficientPermissions(PathBuf), - /// The header does not exist. - NotExist(PathBuf), - /// Clang diagnosed an error. - ClangDiagnostic(String), -} - -impl std::fmt::Display for BindgenError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BindgenError::FolderAsHeader(h) => { - write!(f, "'{}' is a folder", h.display()) - } - BindgenError::InsufficientPermissions(h) => { - write!(f, "insufficient permissions to read '{}'", h.display()) - } - BindgenError::NotExist(h) => { - write!(f, "header '{}' does not exist.", h.display()) - } - BindgenError::ClangDiagnostic(message) => { - write!(f, "clang diagnosed error: {}", message) - } - } - } -} - -impl std::error::Error for BindgenError {} - -/// Generated Rust bindings. -#[derive(Debug)] -pub struct Bindings { - options: BindgenOptions, - module: proc_macro2::TokenStream, -} - -pub(crate) const HOST_TARGET: &str = - include_str!(concat!(env!("OUT_DIR"), "/host-target.txt")); - -// Some architecture triplets are different between rust and libclang, see #1211 -// and duplicates. -fn rust_to_clang_target(rust_target: &str) -> String { - if rust_target.starts_with("aarch64-apple-") { - let mut clang_target = "arm64-apple-".to_owned(); - clang_target - .push_str(rust_target.strip_prefix("aarch64-apple-").unwrap()); - return clang_target; - } else if rust_target.starts_with("riscv64gc-") { - let mut clang_target = "riscv64-".to_owned(); - clang_target.push_str(rust_target.strip_prefix("riscv64gc-").unwrap()); - return clang_target; - } - rust_target.to_owned() -} - -/// Returns the effective target, and whether it was explicitly specified on the -/// clang flags. -fn find_effective_target(clang_args: &[String]) -> (String, bool) { - let mut args = clang_args.iter(); - while let Some(opt) = args.next() { - if opt.starts_with("--target=") { - let mut split = opt.split('='); - split.next(); - return (split.next().unwrap().to_owned(), true); - } - - if opt == "-target" { - if let Some(target) = args.next() { - return (target.clone(), true); - } - } - } - - // If we're running from a build script, try to find the cargo target. - if let Ok(t) = env::var("TARGET") { - return (rust_to_clang_target(&t), false); - } - - (rust_to_clang_target(HOST_TARGET), false) -} - -impl Bindings { - /// Generate bindings for the given options. - pub(crate) fn generate( - mut options: BindgenOptions, - ) -> Result { - ensure_libclang_is_loaded(); - - #[cfg(feature = "runtime")] - debug!( - "Generating bindings, libclang at {}", - clang_sys::get_library().unwrap().path().display() - ); - #[cfg(not(feature = "runtime"))] - debug!("Generating bindings, libclang linked"); - - options.build(); - - let (effective_target, explicit_target) = - find_effective_target(&options.clang_args); - - let is_host_build = - rust_to_clang_target(HOST_TARGET) == effective_target; - - // NOTE: The is_host_build check wouldn't be sound normally in some - // cases if we were to call a binary (if you have a 32-bit clang and are - // building on a 64-bit system for example). But since we rely on - // opening libclang.so, it has to be the same architecture and thus the - // check is fine. - if !explicit_target && !is_host_build { - options - .clang_args - .insert(0, format!("--target={}", effective_target)); - }; - - fn detect_include_paths(options: &mut BindgenOptions) { - if !options.detect_include_paths { - return; - } - - // Filter out include paths and similar stuff, so we don't incorrectly - // promote them to `-isystem`. - let clang_args_for_clang_sys = { - let mut last_was_include_prefix = false; - options - .clang_args - .iter() - .filter(|arg| { - if last_was_include_prefix { - last_was_include_prefix = false; - return false; - } - - let arg = &**arg; - - // https://clang.llvm.org/docs/ClangCommandLineReference.html - // -isystem and -isystem-after are harmless. - if arg == "-I" || arg == "--include-directory" { - last_was_include_prefix = true; - return false; - } - - if arg.starts_with("-I") || - arg.starts_with("--include-directory=") - { - return false; - } - - true - }) - .cloned() - .collect::>() - }; - - debug!( - "Trying to find clang with flags: {:?}", - clang_args_for_clang_sys - ); - - let clang = match clang_sys::support::Clang::find( - None, - &clang_args_for_clang_sys, - ) { - None => return, - Some(clang) => clang, - }; - - debug!("Found clang: {:?}", clang); - - // Whether we are working with C or C++ inputs. - let is_cpp = args_are_cpp(&options.clang_args) || - options.input_header.as_deref().map_or(false, file_is_cpp); - - let search_paths = if is_cpp { - clang.cpp_search_paths - } else { - clang.c_search_paths - }; - - if let Some(search_paths) = search_paths { - for path in search_paths.into_iter() { - if let Ok(path) = path.into_os_string().into_string() { - options.clang_args.push("-isystem".to_owned()); - options.clang_args.push(path); - } - } - } - } - - detect_include_paths(&mut options); - - #[cfg(unix)] - fn can_read(perms: &std::fs::Permissions) -> bool { - use std::os::unix::fs::PermissionsExt; - perms.mode() & 0o444 > 0 - } - - #[cfg(not(unix))] - fn can_read(_: &std::fs::Permissions) -> bool { - true - } - - if let Some(h) = options.input_header.as_ref() { - let path = Path::new(h); - if let Ok(md) = std::fs::metadata(path) { - if md.is_dir() { - return Err(BindgenError::FolderAsHeader(path.into())); - } - if !can_read(&md.permissions()) { - return Err(BindgenError::InsufficientPermissions( - path.into(), - )); - } - options.clang_args.push(h.clone()) - } else { - return Err(BindgenError::NotExist(path.into())); - } - } - - for (idx, f) in options.input_unsaved_files.iter().enumerate() { - if idx != 0 || options.input_header.is_some() { - options.clang_args.push("-include".to_owned()); - } - options.clang_args.push(f.name.to_str().unwrap().to_owned()) - } - - debug!("Fixed-up options: {:?}", options); - - let time_phases = options.time_phases; - let mut context = BindgenContext::new(options); - - if is_host_build { - debug_assert_eq!( - context.target_pointer_size(), - std::mem::size_of::<*mut ()>(), - "{:?} {:?}", - effective_target, - HOST_TARGET - ); - } - - { - let _t = time::Timer::new("parse").with_output(time_phases); - parse(&mut context)?; - } - - let (items, options) = codegen::codegen(context); - - Ok(Bindings { - options, - module: quote! { - #( #items )* - }, - }) - } - - /// Write these bindings as source text to a file. - pub fn write_to_file>(&self, path: P) -> io::Result<()> { - let file = OpenOptions::new() - .write(true) - .truncate(true) - .create(true) - .open(path.as_ref())?; - self.write(Box::new(file))?; - Ok(()) - } - - /// Write these bindings as source text to the given `Write`able. - pub fn write<'a>(&self, mut writer: Box) -> io::Result<()> { - if !self.options.disable_header_comment { - let version = option_env!("CARGO_PKG_VERSION"); - let header = format!( - "/* automatically generated by rust-bindgen {} */\n\n", - version.unwrap_or("(unknown version)") - ); - writer.write_all(header.as_bytes())?; - } - - for line in self.options.raw_lines.iter() { - writer.write_all(line.as_bytes())?; - writer.write_all("\n".as_bytes())?; - } - - if !self.options.raw_lines.is_empty() { - writer.write_all("\n".as_bytes())?; - } - - let bindings = self.module.to_string(); - - match self.rustfmt_generated_string(&bindings) { - Ok(rustfmt_bindings) => { - writer.write_all(rustfmt_bindings.as_bytes())?; - } - Err(err) => { - eprintln!( - "Failed to run rustfmt: {} (non-fatal, continuing)", - err - ); - writer.write_all(bindings.as_bytes())?; - } - } - Ok(()) - } - - /// Gets the rustfmt path to rustfmt the generated bindings. - fn rustfmt_path(&self) -> io::Result> { - debug_assert!(self.options.rustfmt_bindings); - 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())); - } - #[cfg(feature = "which-rustfmt")] - match which::which("rustfmt") { - Ok(p) => Ok(Cow::Owned(p)), - Err(e) => { - Err(io::Error::new(io::ErrorKind::Other, format!("{}", e))) - } - } - #[cfg(not(feature = "which-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())) - } - - /// Checks if rustfmt_bindings is set and runs rustfmt on the string - fn rustfmt_generated_string<'a>( - &self, - source: &'a str, - ) -> io::Result> { - let _t = time::Timer::new("rustfmt_generated_string") - .with_output(self.options.time_phases); - - if !self.options.rustfmt_bindings { - return Ok(Cow::Borrowed(source)); - } - - let rustfmt = self.rustfmt_path()?; - let mut cmd = Command::new(&*rustfmt); - - cmd.stdin(Stdio::piped()).stdout(Stdio::piped()); - - if let Some(path) = self - .options - .rustfmt_configuration_file - .as_ref() - .and_then(|f| f.to_str()) - { - cmd.args(&["--config-path", path]); - } - - let mut child = cmd.spawn()?; - let mut child_stdin = child.stdin.take().unwrap(); - let mut child_stdout = child.stdout.take().unwrap(); - - let source = source.to_owned(); - - // Write to stdin in a new thread, so that we can read from stdout on this - // thread. This keeps the child from blocking on writing to its stdout which - // might block us from writing to its stdin. - let stdin_handle = ::std::thread::spawn(move || { - let _ = child_stdin.write_all(source.as_bytes()); - source - }); - - let mut output = vec![]; - io::copy(&mut child_stdout, &mut output)?; - - let status = child.wait()?; - let source = stdin_handle.join().expect( - "The thread writing to rustfmt's stdin doesn't do \ - anything that could panic", - ); - - match String::from_utf8(output) { - Ok(bindings) => match status.code() { - Some(0) => Ok(Cow::Owned(bindings)), - Some(2) => Err(io::Error::new( - io::ErrorKind::Other, - "Rustfmt parsing errors.".to_string(), - )), - Some(3) => { - warn!("Rustfmt could not format some lines."); - Ok(Cow::Owned(bindings)) - } - _ => Err(io::Error::new( - io::ErrorKind::Other, - "Internal rustfmt error".to_string(), - )), - }, - _ => Ok(Cow::Owned(source)), - } - } -} - -impl std::fmt::Display for Bindings { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut bytes = vec![]; - self.write(Box::new(&mut bytes) as Box) - .expect("writing to a vec cannot fail"); - f.write_str( - std::str::from_utf8(&bytes) - .expect("we should only write bindings that are valid utf-8"), - ) - } -} - -/// Determines whether the given cursor is in any of the files matched by the -/// options. -fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { - ctx.options().builtins || !cursor.is_builtin() -} - -/// Parse one `Item` from the Clang cursor. -fn parse_one( - ctx: &mut BindgenContext, - cursor: clang::Cursor, - parent: Option, -) -> clang_sys::CXChildVisitResult { - if !filter_builtins(ctx, &cursor) { - return CXChildVisit_Continue; - } - - use clang_sys::CXChildVisit_Continue; - match Item::parse(cursor, parent, ctx) { - Ok(..) => {} - Err(ParseError::Continue) => {} - Err(ParseError::Recurse) => { - cursor.visit(|child| parse_one(ctx, child, parent)); - } - } - CXChildVisit_Continue -} - -/// Parse the Clang AST into our `Item` internal representation. -fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { - use clang_sys::*; - - let mut error = None; - for d in context.translation_unit().diags().iter() { - let msg = d.format(); - let is_err = d.severity() >= CXDiagnostic_Error; - if is_err { - let error = error.get_or_insert_with(String::new); - error.push_str(&msg); - error.push('\n'); - } else { - eprintln!("clang diag: {}", msg); - } - } - - if let Some(message) = error { - return Err(BindgenError::ClangDiagnostic(message)); - } - - let cursor = context.translation_unit().cursor(); - - if context.options().emit_ast { - fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { - if !cur.is_builtin() { - clang::ast_dump(cur, 0) - } else { - CXChildVisit_Continue - } - } - cursor.visit(|cur| dump_if_not_builtin(&cur)); - } - - let root = context.root_module(); - context.with_module(root, |context| { - cursor.visit(|cursor| parse_one(context, cursor, None)) - }); - - assert!( - context.current_module() == context.root_module(), - "How did this happen?" - ); - Ok(()) -} - -/// Extracted Clang version data -#[derive(Debug)] -pub struct ClangVersion { - /// Major and minor semver, if parsing was successful - pub parsed: Option<(u32, u32)>, - /// full version string - pub full: String, -} - -/// Get the major and the minor semver numbers of Clang's version -pub fn clang_version() -> ClangVersion { - ensure_libclang_is_loaded(); - - //Debian clang version 11.0.1-2 - 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())) - .map(|v| v.split('.').collect()); - if let Some(v) = split_v { - if v.len() >= 2 { - let maybe_major = v[0].parse::(); - let maybe_minor = v[1].parse::(); - if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) { - return ClangVersion { - parsed: Some((major, minor)), - full: raw_v.clone(), - }; - } - } - }; - ClangVersion { - parsed: None, - full: raw_v.clone(), - } -} - -/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found. -fn get_target_dependent_env_var(var: &str) -> Option { - if let Ok(target) = env::var("TARGET") { - if let Ok(v) = env::var(&format!("{}_{}", var, target)) { - return Some(v); - } - if let Ok(v) = - env::var(&format!("{}_{}", var, target.replace("-", "_"))) - { - return Some(v); - } - } - env::var(var).ok() -} - -/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed -/// line -/// -/// When running inside a `build.rs` script, this can be used to make cargo invalidate the -/// generated bindings whenever any of the files included from the header change: -/// ``` -/// use bindgen::builder; -/// let bindings = builder() -/// .header("path/to/input/header") -/// .parse_callbacks(Box::new(bindgen::CargoCallbacks)) -/// .generate(); -/// ``` -#[derive(Debug)] -pub struct CargoCallbacks; - -impl callbacks::ParseCallbacks for CargoCallbacks { - fn include_file(&self, filename: &str) { - println!("cargo:rerun-if-changed={}", filename); - } -} - -/// Test command_line_flag function. -#[test] -fn commandline_flag_unit_test_function() { - //Test 1 - let bindings = crate::builder(); - let command_line_flags = bindings.command_line_flags(); - - let test_cases = vec![ - "--rust-target", - "--no-derive-default", - "--generate", - "functions,types,vars,methods,constructors,destructors", - ] - .iter() - .map(|&x| x.into()) - .collect::>(); - - assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); - - //Test 2 - let bindings = crate::builder() - .header("input_header") - .allowlist_type("Distinct_Type") - .allowlist_function("safe_function"); - - let command_line_flags = bindings.command_line_flags(); - let test_cases = vec![ - "--rust-target", - "input_header", - "--no-derive-default", - "--generate", - "functions,types,vars,methods,constructors,destructors", - "--allowlist-type", - "Distinct_Type", - "--allowlist-function", - "safe_function", - ] - .iter() - .map(|&x| x.into()) - .collect::>(); - println!("{:?}", command_line_flags); - - assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); -} - -#[test] -fn test_rust_to_clang_target() { - assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios"); -} - -#[test] -fn test_rust_to_clang_target_riscv() { - assert_eq!( - rust_to_clang_target("riscv64gc-unknown-linux-gnu"), - "riscv64-unknown-linux-gnu" - ) -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index a208957410..0000000000 --- a/src/main.rs +++ /dev/null @@ -1,111 +0,0 @@ -extern crate bindgen; -#[cfg(feature = "logging")] -extern crate env_logger; -#[macro_use] -#[cfg(feature = "logging")] -extern crate log; -extern crate clap; - -use bindgen::clang_version; -use std::env; -use std::panic; - -#[macro_use] -#[cfg(not(feature = "logging"))] -mod log_stubs; - -mod options; -use crate::options::builder_from_flags; - -fn clang_version_check() { - let version = clang_version(); - let expected_version = if cfg!(feature = "testing_only_libclang_9") { - Some((9, 0)) - } else if cfg!(feature = "testing_only_libclang_5") { - Some((5, 0)) - } else if cfg!(feature = "testing_only_libclang_4") { - Some((4, 0)) - } else { - None - }; - - info!( - "Clang Version: {}, parsed: {:?}", - version.full, version.parsed - ); - - if expected_version.is_some() { - // assert_eq!(version.parsed, version.parsed); - } -} - -pub fn main() { - #[cfg(feature = "logging")] - env_logger::init(); - - match builder_from_flags(env::args()) { - Ok((builder, output, verbose)) => { - clang_version_check(); - let builder_result = panic::catch_unwind(|| { - builder.generate().expect("Unable to generate bindings") - }); - - if builder_result.is_err() { - if verbose { - print_verbose_err(); - } - std::process::exit(1); - } - - let bindings = builder_result.unwrap(); - bindings.write(output).expect("Unable to write output"); - } - Err(error) => { - println!("{}", error); - std::process::exit(1); - } - }; -} - -fn print_verbose_err() { - println!("Bindgen unexpectedly panicked"); - println!( - "This may be caused by one of the known-unsupported \ - things (https://rust-lang.github.io/rust-bindgen/cpp.html), \ - please modify the bindgen flags to work around it as \ - described in https://rust-lang.github.io/rust-bindgen/cpp.html" - ); - println!( - "Otherwise, please file an issue at \ - https://github.com/rust-lang/rust-bindgen/issues/new" - ); -} - -#[cfg(test)] -mod test { - fn build_flags_output_helper(builder: &bindgen::Builder) { - let mut command_line_flags = builder.command_line_flags(); - command_line_flags.insert(0, "bindgen".to_string()); - - let flags_quoted: Vec = command_line_flags - .iter() - .map(|x| format!("{}", shlex::quote(x))) - .collect(); - let flags_str = flags_quoted.join(" "); - println!("{}", flags_str); - - let (builder, _output, _verbose) = - crate::options::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() - .header("tests/headers/char.h") - .header("tests/headers/func_ptr.h") - .header("tests/headers/16-byte-alignment.h"); - build_flags_output_helper(&bindings); - } -} diff --git a/src/options.rs b/src/options.rs deleted file mode 100644 index 081aad61da..0000000000 --- a/src/options.rs +++ /dev/null @@ -1,1021 +0,0 @@ -use bindgen::{ - builder, AliasVariation, Builder, CodegenConfig, EnumVariation, - MacroTypeVariation, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, - RUST_TARGET_STRINGS, -}; -use clap::{App, Arg}; -use std::fs::File; -use std::io::{self, stderr, Error, ErrorKind, Write}; -use std::path::PathBuf; -use std::str::FromStr; - -/// Construct a new [`Builder`](./struct.Builder.html) from command line flags. -pub fn builder_from_flags( - args: I, -) -> Result<(Builder, Box, bool), io::Error> -where - I: Iterator, -{ - let rust_target_help = format!( - "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {:?}.", - RUST_TARGET_STRINGS, - String::from(RustTarget::default()) - ); - - let matches = App::new("bindgen") - .version(option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")) - .about("Generates Rust bindings from C/C++ headers.") - .override_usage("bindgen [FLAGS] [OPTIONS]
-- ...") - .args(&[ - Arg::new("header") - .help("C or C++ header file") - .required(true), - Arg::new("depfile") - .long("depfile") - .takes_value(true) - .help("Path to write depfile to"), - Arg::new("default-enum-style") - .long("default-enum-style") - .help("The default style of code used to generate enums.") - .value_name("variant") - .default_value("consts") - .possible_values(&[ - "consts", - "moduleconsts", - "bitfield", - "newtype", - "rust", - "rust_non_exhaustive", - ]) - .multiple_occurrences(false), - Arg::new("bitfield-enum") - .long("bitfield-enum") - .help( - "Mark any enum whose name matches as a set of \ - bitfield flags.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("newtype-enum") - .long("newtype-enum") - .help("Mark any enum whose name matches as a newtype.") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("rustified-enum") - .long("rustified-enum") - .help("Mark any enum whose name matches as a Rust enum.") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("constified-enum") - .long("constified-enum") - .help( - "Mark any enum whose name matches as a series of \ - constants.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("constified-enum-module") - .long("constified-enum-module") - .help( - "Mark any enum whose name matches as a module of \ - constants.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("default-macro-constant-type") - .long("default-macro-constant-type") - .help("The default signed/unsigned type for C macro constants.") - .value_name("variant") - .default_value("unsigned") - .possible_values(&["signed", "unsigned"]) - .multiple_occurrences(false), - Arg::new("default-alias-style") - .long("default-alias-style") - .help("The default style of code used to generate typedefs.") - .value_name("variant") - .default_value("type_alias") - .possible_values(&[ - "type_alias", - "new_type", - "new_type_deref", - ]) - .multiple_occurrences(false), - Arg::new("normal-alias") - .long("normal-alias") - .help( - "Mark any typedef alias whose name matches to use \ - normal type aliasing.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("new-type-alias") - .long("new-type-alias") - .help( - "Mark any typedef alias whose name matches to have \ - a new type generated for it.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("new-type-alias-deref") - .long("new-type-alias-deref") - .help( - "Mark any typedef alias whose name matches to have \ - a new type with Deref and DerefMut to the inner type.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("blocklist-type") - .alias("blacklist-type") - .long("blocklist-type") - .help("Mark as hidden.") - .value_name("type") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("blocklist-function") - .alias("blacklist-function") - .long("blocklist-function") - .help("Mark as hidden.") - .value_name("function") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("blocklist-item") - .alias("blacklist-item") - .long("blocklist-item") - .help("Mark as hidden.") - .value_name("item") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("blocklist-file") - .alias("blacklist-file") - .long("blocklist-file") - .help("Mark all contents of as hidden.") - .value_name("path") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("no-layout-tests") - .long("no-layout-tests") - .help("Avoid generating layout tests for any type."), - Arg::new("no-derive-copy") - .long("no-derive-copy") - .help("Avoid deriving Copy on any type."), - Arg::new("no-derive-debug") - .long("no-derive-debug") - .help("Avoid deriving Debug on any type."), - Arg::new("no-derive-default") - .long("no-derive-default") - .hide(true) - .help("Avoid deriving Default on any type."), - Arg::new("impl-debug").long("impl-debug").help( - "Create Debug implementation, if it can not be derived \ - automatically.", - ), - Arg::new("impl-partialeq") - .long("impl-partialeq") - .help( - "Create PartialEq implementation, if it can not be derived \ - automatically.", - ), - Arg::new("with-derive-default") - .long("with-derive-default") - .help("Derive Default on any type."), - Arg::new("with-derive-hash") - .long("with-derive-hash") - .help("Derive hash on any type."), - Arg::new("with-derive-partialeq") - .long("with-derive-partialeq") - .help("Derive partialeq on any type."), - Arg::new("with-derive-partialord") - .long("with-derive-partialord") - .help("Derive partialord on any type."), - Arg::new("with-derive-eq") - .long("with-derive-eq") - .help( - "Derive eq on any type. Enable this option also \ - enables --with-derive-partialeq", - ), - Arg::new("with-derive-ord") - .long("with-derive-ord") - .help( - "Derive ord on any type. Enable this option also \ - enables --with-derive-partialord", - ), - Arg::new("no-doc-comments") - .long("no-doc-comments") - .help( - "Avoid including doc comments in the output, see: \ - https://github.com/rust-lang/rust-bindgen/issues/426", - ), - Arg::new("no-recursive-allowlist") - .long("no-recursive-allowlist") - .alias("no-recursive-whitelist") - .help( - "Disable allowlisting types recursively. This will cause \ - bindgen to emit Rust code that won't compile! See the \ - `bindgen::Builder::allowlist_recursively` method's \ - documentation for details.", - ), - Arg::new("objc-extern-crate") - .long("objc-extern-crate") - .help("Use extern crate instead of use for objc."), - Arg::new("generate-block") - .long("generate-block") - .help("Generate block signatures instead of void pointers."), - Arg::new("block-extern-crate") - .long("block-extern-crate") - .help("Use extern crate instead of use for block."), - Arg::new("distrust-clang-mangling") - .long("distrust-clang-mangling") - .help("Do not trust the libclang-provided mangling"), - Arg::new("builtins").long("builtins").help( - "Output bindings for builtin definitions, e.g. \ - __builtin_va_list.", - ), - Arg::new("ctypes-prefix") - .long("ctypes-prefix") - .help( - "Use the given prefix before raw types instead of \ - ::std::os::raw.", - ) - .value_name("prefix") - .takes_value(true), - Arg::new("anon-fields-prefix") - .long("anon-fields-prefix") - .help("Use the given prefix for the anon fields.") - .value_name("prefix") - .default_value(DEFAULT_ANON_FIELDS_PREFIX) - .takes_value(true), - Arg::new("time-phases") - .long("time-phases") - .help("Time the different bindgen phases and print to stderr"), - // All positional arguments after the end of options marker, `--` - Arg::new("clang-args").last(true).multiple_occurrences(true), - Arg::new("emit-clang-ast") - .long("emit-clang-ast") - .help("Output the Clang AST for debugging purposes."), - Arg::new("emit-ir") - .long("emit-ir") - .help("Output our internal IR for debugging purposes."), - Arg::new("emit-ir-graphviz") - .long("emit-ir-graphviz") - .help("Dump graphviz dot file.") - .value_name("path") - .takes_value(true), - Arg::new("enable-cxx-namespaces") - .long("enable-cxx-namespaces") - .help("Enable support for C++ namespaces."), - Arg::new("disable-name-namespacing") - .long("disable-name-namespacing") - .help( - "Disable namespacing via mangling, causing bindgen to \ - generate names like \"Baz\" instead of \"foo_bar_Baz\" \ - for an input name \"foo::bar::Baz\".", - ), - Arg::new("disable-nested-struct-naming") - .long("disable-nested-struct-naming") - .help( - "Disable nested struct naming, causing bindgen to generate \ - names like \"bar\" instead of \"foo_bar\" for a nested \ - definition \"struct foo { struct bar { } b; };\"." - ), - Arg::new("disable-untagged-union") - .long("disable-untagged-union") - .help( - "Disable support for native Rust unions.", - ), - Arg::new("disable-header-comment") - .long("disable-header-comment") - .help("Suppress insertion of bindgen's version identifier into generated bindings.") - .multiple_occurrences(true), - Arg::new("ignore-functions") - .long("ignore-functions") - .help( - "Do not generate bindings for functions or methods. This \ - is useful when you only care about struct layouts.", - ), - Arg::new("generate") - .long("generate") - .help( - "Generate only given items, split by commas. \ - Valid values are \"functions\",\"types\", \"vars\", \ - \"methods\", \"constructors\" and \"destructors\".", - ) - .takes_value(true), - Arg::new("ignore-methods") - .long("ignore-methods") - .help("Do not generate bindings for methods."), - Arg::new("no-convert-floats") - .long("no-convert-floats") - .help("Do not automatically convert floats to f32/f64."), - Arg::new("no-prepend-enum-name") - .long("no-prepend-enum-name") - .help("Do not prepend the enum name to constant or newtype variants."), - Arg::new("no-include-path-detection") - .long("no-include-path-detection") - .help("Do not try to detect default include paths"), - Arg::new("fit-macro-constant-types") - .long("fit-macro-constant-types") - .help("Try to fit macro constants into types smaller than u32/i32"), - Arg::new("unstable-rust") - .long("unstable-rust") - .help("Generate unstable Rust code (deprecated; use --rust-target instead).") - .multiple_occurrences(true), // FIXME: Pass legacy test suite - Arg::new("opaque-type") - .long("opaque-type") - .help("Mark as opaque.") - .value_name("type") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("output") - .short('o') - .long("output") - .help("Write Rust bindings to .") - .takes_value(true), - Arg::new("raw-line") - .long("raw-line") - .help("Add a raw line of Rust code at the beginning of output.") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("module-raw-line") - .long("module-raw-line") - .help("Add a raw line of Rust code to a given module.") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(2) - .value_names(&["module-name", "raw-line"]), - Arg::new("rust-target") - .long("rust-target") - .help(rust_target_help.as_ref()) - .takes_value(true), - Arg::new("use-core") - .long("use-core") - .help("Use types from Rust core instead of std."), - Arg::new("conservative-inline-namespaces") - .long("conservative-inline-namespaces") - .help( - "Conservatively generate inline namespaces to avoid name \ - conflicts.", - ), - Arg::new("use-msvc-mangling") - .long("use-msvc-mangling") - .help("MSVC C++ ABI mangling. DEPRECATED: Has no effect."), - Arg::new("allowlist-function") - .long("allowlist-function") - .alias("whitelist-function") - .help( - "Allowlist all the free-standing functions matching \ - . Other non-allowlisted functions will not be \ - generated.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("generate-inline-functions") - .long("generate-inline-functions") - .help("Generate inline functions."), - Arg::new("allowlist-type") - .long("allowlist-type") - .alias("whitelist-type") - .help( - "Only generate types matching . Other non-allowlisted types will \ - not be generated.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("allowlist-var") - .long("allowlist-var") - .alias("whitelist-var") - .help( - "Allowlist all the free-standing variables matching \ - . Other non-allowlisted variables will not be \ - generated.", - ) - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("allowlist-file") - .alias("allowlist-file") - .long("allowlist-file") - .help("Allowlist all contents of .") - .value_name("path") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("verbose") - .long("verbose") - .help("Print verbose error messages."), - Arg::new("dump-preprocessed-input") - .long("dump-preprocessed-input") - .help( - "Preprocess and dump the input header files to disk. \ - Useful when debugging bindgen, using C-Reduce, or when \ - filing issues. The resulting file will be named \ - something like `__bindgen.i` or `__bindgen.ii`.", - ), - Arg::new("no-record-matches") - .long("no-record-matches") - .help( - "Do not record matching items in the regex sets. \ - This disables reporting of unused items.", - ), - Arg::new("size_t-is-usize") - .long("size_t-is-usize") - .help("Translate size_t to usize."), - Arg::new("no-rustfmt-bindings") - .long("no-rustfmt-bindings") - .help("Do not format the generated bindings with rustfmt."), - Arg::new("rustfmt-bindings") - .long("rustfmt-bindings") - .help( - "Format the generated bindings with rustfmt. DEPRECATED: \ - --rustfmt-bindings is now enabled by default. Disable \ - with --no-rustfmt-bindings.", - ), - Arg::new("rustfmt-configuration-file") - .long("rustfmt-configuration-file") - .help( - "The absolute path to the rustfmt configuration file. \ - The configuration file will be used for formatting the bindings. \ - This parameter is incompatible with --no-rustfmt-bindings.", - ) - .value_name("path") - .takes_value(true) - .multiple_occurrences(false) - .number_of_values(1), - Arg::new("no-partialeq") - .long("no-partialeq") - .help("Avoid deriving PartialEq for types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("no-copy") - .long("no-copy") - .help("Avoid deriving Copy for types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("no-debug") - .long("no-debug") - .help("Avoid deriving Debug for types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("no-default") - .long("no-default") - .help("Avoid deriving/implement Default for types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("no-hash") - .long("no-hash") - .help("Avoid deriving Hash for types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("must-use-type") - .long("must-use-type") - .help("Add #[must_use] annotation to types matching .") - .value_name("regex") - .takes_value(true) - .multiple_occurrences(true) - .number_of_values(1), - Arg::new("enable-function-attribute-detection") - .long("enable-function-attribute-detection") - .help( - "Enables detecting unexposed attributes in functions (slow). - Used to generate #[must_use] annotations.", - ), - Arg::new("use-array-pointers-in-arguments") - .long("use-array-pointers-in-arguments") - .help("Use `*const [T; size]` instead of `*const T` for C arrays"), - Arg::new("wasm-import-module-name") - .long("wasm-import-module-name") - .value_name("name") - .takes_value(true) - .help("The name to be used in a #[link(wasm_import_module = ...)] statement"), - Arg::new("dynamic-loading") - .long("dynamic-loading") - .takes_value(true) - .help("Use dynamic loading mode with the given library name."), - Arg::new("dynamic-link-require-all") - .long("dynamic-link-require-all") - .help("Require successful linkage to all functions in the library."), - Arg::new("respect-cxx-access-specs") - .long("respect-cxx-access-specs") - .help("Makes generated bindings `pub` only for items if the items are publically accessible in C++."), - Arg::new("translate-enum-integer-types") - .long("translate-enum-integer-types") - .help("Always translate enum integer types to native Rust integer types."), - Arg::new("c-naming") - .long("c-naming") - .help("Generate types with C style naming."), - Arg::new("explicit-padding") - .long("explicit-padding") - .help("Always output explicit padding fields."), - Arg::new("vtable-generation") - .long("vtable-generation") - .help("Enables generation of vtable functions."), - ]) // .args() - .get_matches_from(args); - - let mut builder = builder(); - - if let Some(header) = matches.value_of("header") { - builder = builder.header(header); - } else { - return Err(Error::new(ErrorKind::Other, "Header not found")); - } - - if matches.is_present("unstable-rust") { - builder = builder.rust_target(RustTarget::Nightly); - writeln!( - &mut stderr(), - "warning: the `--unstable-rust` option is deprecated" - ) - .expect("Unable to write error message"); - } - - if let Some(rust_target) = matches.value_of("rust-target") { - builder = builder.rust_target(RustTarget::from_str(rust_target)?); - } - - if let Some(variant) = matches.value_of("default-enum-style") { - builder = builder.default_enum_style(EnumVariation::from_str(variant)?) - } - - if let Some(bitfields) = matches.values_of("bitfield-enum") { - for regex in bitfields { - builder = builder.bitfield_enum(regex); - } - } - - if let Some(newtypes) = matches.values_of("newtype-enum") { - for regex in newtypes { - builder = builder.newtype_enum(regex); - } - } - - if let Some(rustifieds) = matches.values_of("rustified-enum") { - for regex in rustifieds { - builder = builder.rustified_enum(regex); - } - } - - if let Some(const_enums) = matches.values_of("constified-enum") { - for regex in const_enums { - builder = builder.constified_enum(regex); - } - } - - if let Some(constified_mods) = matches.values_of("constified-enum-module") { - for regex in constified_mods { - builder = builder.constified_enum_module(regex); - } - } - - if let Some(variant) = matches.value_of("default-macro-constant-type") { - builder = builder - .default_macro_constant_type(MacroTypeVariation::from_str(variant)?) - } - - if let Some(variant) = matches.value_of("default-alias-style") { - builder = - builder.default_alias_style(AliasVariation::from_str(variant)?); - } - - if let Some(type_alias) = matches.values_of("normal-alias") { - for regex in type_alias { - builder = builder.type_alias(regex); - } - } - - if let Some(new_type) = matches.values_of("new-type-alias") { - for regex in new_type { - builder = builder.new_type_alias(regex); - } - } - - if let Some(new_type_deref) = matches.values_of("new-type-alias-deref") { - for regex in new_type_deref { - builder = builder.new_type_alias_deref(regex); - } - } - - if let Some(hidden_types) = matches.values_of("blocklist-type") { - for ty in hidden_types { - builder = builder.blocklist_type(ty); - } - } - - if let Some(hidden_functions) = matches.values_of("blocklist-function") { - for fun in hidden_functions { - builder = builder.blocklist_function(fun); - } - } - - if let Some(hidden_identifiers) = matches.values_of("blocklist-item") { - for id in hidden_identifiers { - builder = builder.blocklist_item(id); - } - } - - if let Some(hidden_files) = matches.values_of("blocklist-file") { - for file in hidden_files { - builder = builder.blocklist_file(file); - } - } - - if matches.is_present("builtins") { - builder = builder.emit_builtins(); - } - - if matches.is_present("no-layout-tests") { - builder = builder.layout_tests(false); - } - - if matches.is_present("no-derive-copy") { - builder = builder.derive_copy(false); - } - - if matches.is_present("no-derive-debug") { - builder = builder.derive_debug(false); - } - - if matches.is_present("impl-debug") { - builder = builder.impl_debug(true); - } - - if matches.is_present("impl-partialeq") { - builder = builder.impl_partialeq(true); - } - - if matches.is_present("with-derive-default") { - builder = builder.derive_default(true); - } - - if matches.is_present("with-derive-hash") { - builder = builder.derive_hash(true); - } - - if matches.is_present("with-derive-partialeq") { - builder = builder.derive_partialeq(true); - } - - if matches.is_present("with-derive-partialord") { - builder = builder.derive_partialord(true); - } - - if matches.is_present("with-derive-eq") { - builder = builder.derive_eq(true); - } - - if matches.is_present("with-derive-ord") { - builder = builder.derive_ord(true); - } - - if matches.is_present("no-derive-default") { - builder = builder.derive_default(false); - } - - if matches.is_present("no-prepend-enum-name") { - builder = builder.prepend_enum_name(false); - } - - if matches.is_present("no-include-path-detection") { - builder = builder.detect_include_paths(false); - } - - if matches.is_present("fit-macro-constant-types") { - builder = builder.fit_macro_constants(true); - } - - if matches.is_present("time-phases") { - builder = builder.time_phases(true); - } - - if matches.is_present("use-array-pointers-in-arguments") { - builder = builder.array_pointers_in_arguments(true); - } - - if let Some(wasm_import_name) = matches.value_of("wasm-import-module-name") - { - builder = builder.wasm_import_module_name(wasm_import_name); - } - - if let Some(prefix) = matches.value_of("ctypes-prefix") { - builder = builder.ctypes_prefix(prefix); - } - - if let Some(prefix) = matches.value_of("anon-fields-prefix") { - builder = builder.anon_fields_prefix(prefix); - } - - if let Some(what_to_generate) = matches.value_of("generate") { - let mut config = CodegenConfig::empty(); - for what in what_to_generate.split(',') { - match what { - "functions" => config.insert(CodegenConfig::FUNCTIONS), - "types" => config.insert(CodegenConfig::TYPES), - "vars" => config.insert(CodegenConfig::VARS), - "methods" => config.insert(CodegenConfig::METHODS), - "constructors" => config.insert(CodegenConfig::CONSTRUCTORS), - "destructors" => config.insert(CodegenConfig::DESTRUCTORS), - otherwise => { - return Err(Error::new( - ErrorKind::Other, - format!("Unknown generate item: {}", otherwise), - )); - } - } - } - builder = builder.with_codegen_config(config); - } - - if matches.is_present("emit-clang-ast") { - builder = builder.emit_clang_ast(); - } - - if matches.is_present("emit-ir") { - builder = builder.emit_ir(); - } - - if let Some(path) = matches.value_of("emit-ir-graphviz") { - builder = builder.emit_ir_graphviz(path); - } - - if matches.is_present("enable-cxx-namespaces") { - builder = builder.enable_cxx_namespaces(); - } - - if matches.is_present("enable-function-attribute-detection") { - builder = builder.enable_function_attribute_detection(); - } - - if matches.is_present("disable-name-namespacing") { - builder = builder.disable_name_namespacing(); - } - - if matches.is_present("disable-nested-struct-naming") { - builder = builder.disable_nested_struct_naming(); - } - - if matches.is_present("disable-untagged-union") { - builder = builder.disable_untagged_union(); - } - - if matches.is_present("disable-header-comment") { - builder = builder.disable_header_comment(); - } - - if matches.is_present("ignore-functions") { - builder = builder.ignore_functions(); - } - - if matches.is_present("ignore-methods") { - builder = builder.ignore_methods(); - } - - if matches.is_present("no-convert-floats") { - builder = builder.no_convert_floats(); - } - - if matches.is_present("no-doc-comments") { - builder = builder.generate_comments(false); - } - - if matches.is_present("no-recursive-allowlist") { - builder = builder.allowlist_recursively(false); - } - - if matches.is_present("objc-extern-crate") { - builder = builder.objc_extern_crate(true); - } - - if matches.is_present("generate-block") { - builder = builder.generate_block(true); - } - - if matches.is_present("block-extern-crate") { - builder = builder.block_extern_crate(true); - } - - if let Some(opaque_types) = matches.values_of("opaque-type") { - for ty in opaque_types { - builder = builder.opaque_type(ty); - } - } - - if let Some(lines) = matches.values_of("raw-line") { - for line in lines { - builder = builder.raw_line(line); - } - } - - if let Some(mut values) = matches.values_of("module-raw-line") { - while let Some(module) = values.next() { - let line = values.next().unwrap(); - builder = builder.module_raw_line(module, line); - } - } - - if matches.is_present("use-core") { - builder = builder.use_core(); - } - - if matches.is_present("distrust-clang-mangling") { - builder = builder.trust_clang_mangling(false); - } - - if matches.is_present("conservative-inline-namespaces") { - builder = builder.conservative_inline_namespaces(); - } - - if matches.is_present("generate-inline-functions") { - builder = builder.generate_inline_functions(true); - } - - if let Some(allowlist) = matches.values_of("allowlist-function") { - for regex in allowlist { - builder = builder.allowlist_function(regex); - } - } - - if let Some(allowlist) = matches.values_of("allowlist-type") { - for regex in allowlist { - builder = builder.allowlist_type(regex); - } - } - - if let Some(allowlist) = matches.values_of("allowlist-var") { - for regex in allowlist { - builder = builder.allowlist_var(regex); - } - } - - if let Some(hidden_files) = matches.values_of("allowlist-file") { - for file in hidden_files { - builder = builder.allowlist_file(file); - } - } - - if let Some(args) = matches.values_of("clang-args") { - for arg in args { - builder = builder.clang_arg(arg); - } - } - - let output = if let Some(path) = matches.value_of("output") { - let file = File::create(path)?; - if let Some(depfile) = matches.value_of("depfile") { - builder = builder.depfile(path, depfile); - } - Box::new(io::BufWriter::new(file)) as Box - } else { - if let Some(depfile) = matches.value_of("depfile") { - builder = builder.depfile("-", depfile); - } - Box::new(io::BufWriter::new(io::stdout())) as Box - }; - - if matches.is_present("dump-preprocessed-input") { - builder.dump_preprocessed_input()?; - } - - if matches.is_present("no-record-matches") { - builder = builder.record_matches(false); - } - - if matches.is_present("size_t-is-usize") { - builder = builder.size_t_is_usize(true); - } - - let no_rustfmt_bindings = matches.is_present("no-rustfmt-bindings"); - if no_rustfmt_bindings { - builder = builder.rustfmt_bindings(false); - } - - if let Some(path_str) = matches.value_of("rustfmt-configuration-file") { - let path = PathBuf::from(path_str); - - if no_rustfmt_bindings { - return Err(Error::new( - ErrorKind::Other, - "Cannot supply both --rustfmt-configuration-file and --no-rustfmt-bindings", - )); - } - - if !path.is_absolute() { - return Err(Error::new( - ErrorKind::Other, - "--rustfmt-configuration--file needs to be an absolute path!", - )); - } - - if path.to_str().is_none() { - return Err(Error::new( - ErrorKind::Other, - "--rustfmt-configuration-file contains non-valid UTF8 characters.", - )); - } - - builder = builder.rustfmt_configuration_file(Some(path)); - } - - if let Some(no_partialeq) = matches.values_of("no-partialeq") { - for regex in no_partialeq { - builder = builder.no_partialeq(regex); - } - } - - if let Some(no_copy) = matches.values_of("no-copy") { - for regex in no_copy { - builder = builder.no_copy(regex); - } - } - - if let Some(no_debug) = matches.values_of("no-debug") { - for regex in no_debug { - builder = builder.no_debug(regex); - } - } - - if let Some(no_default) = matches.values_of("no-default") { - for regex in no_default { - builder = builder.no_default(regex); - } - } - - if let Some(no_hash) = matches.values_of("no-hash") { - for regex in no_hash { - builder = builder.no_hash(regex); - } - } - - if let Some(must_use_type) = matches.values_of("must-use-type") { - for regex in must_use_type { - builder = builder.must_use_type(regex); - } - } - - if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") { - builder = builder.dynamic_library_name(dynamic_library_name); - } - - if matches.is_present("dynamic-link-require-all") { - builder = builder.dynamic_link_require_all(true); - } - - if matches.is_present("respect-cxx-access-specs") { - builder = builder.respect_cxx_access_specs(true); - } - - if matches.is_present("translate-enum-integer-types") { - builder = builder.translate_enum_integer_types(true); - } - - if matches.is_present("c-naming") { - builder = builder.c_naming(true); - } - - if matches.is_present("explicit-padding") { - builder = builder.explicit_padding(true); - } - - if matches.is_present("vtable-generation") { - builder = builder.vtable_generation(true); - } - - let verbose = matches.is_present("verbose"); - - Ok((builder, output, verbose)) -} diff --git a/src/parse.rs b/src/parse.rs deleted file mode 100644 index f60de43177..0000000000 --- a/src/parse.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Common traits and types related to parsing our IR from Clang cursors. - -use crate::clang; -use crate::ir::context::{BindgenContext, ItemId, TypeId}; -use crate::ir::ty::TypeKind; - -/// Not so much an error in the traditional sense, but a control flow message -/// when walking over Clang's AST with a cursor. -#[derive(Debug)] -pub enum ParseError { - /// Recurse down the current AST node's children. - Recurse, - /// Continue on to the next sibling AST node, or back up to the parent's - /// siblings if we've exhausted all of this node's siblings (and so on). - Continue, -} - -/// The result of parsing a Clang AST node. -#[derive(Debug)] -pub enum ParseResult { - /// We've already resolved this item before, here is the extant `ItemId` for - /// it. - AlreadyResolved(ItemId), - - /// This is a newly parsed item. If the cursor is `Some`, it points to the - /// AST node where the new `T` was declared. - New(T, Option), -} - -/// An intermediate representation "sub-item" (i.e. one of the types contained -/// inside an `ItemKind` variant) that can be parsed from a Clang cursor. -pub trait ClangSubItemParser: Sized { - /// Attempt to parse this type from the given cursor. - /// - /// The fact that is a reference guarantees it's held by the context, and - /// allow returning already existing types. - fn parse( - cursor: clang::Cursor, - context: &mut BindgenContext, - ) -> Result, ParseError>; -} - -/// An intermediate representation item that can be parsed from a Clang cursor. -pub trait ClangItemParser: Sized { - /// Parse this item from the given Clang cursor. - fn parse( - cursor: clang::Cursor, - parent: Option, - context: &mut BindgenContext, - ) -> Result; - - /// Parse this item from the given Clang type. - fn from_ty( - ty: &clang::Type, - location: clang::Cursor, - parent: Option, - ctx: &mut BindgenContext, - ) -> Result; - - /// Identical to `from_ty`, but use the given `id` as the `ItemId` for the - /// newly parsed item. - fn from_ty_with_id( - id: ItemId, - ty: &clang::Type, - location: clang::Cursor, - parent: Option, - ctx: &mut BindgenContext, - ) -> Result; - - /// Parse this item from the given Clang type, or if we haven't resolved all - /// the other items this one depends on, an unresolved reference. - fn from_ty_or_ref( - ty: clang::Type, - location: clang::Cursor, - parent_id: Option, - context: &mut BindgenContext, - ) -> TypeId; - - /// Identical to `from_ty_or_ref`, but use the given `potential_id` as the - /// `ItemId` for the newly parsed item. - fn from_ty_or_ref_with_id( - potential_id: ItemId, - ty: clang::Type, - location: clang::Cursor, - parent_id: Option, - context: &mut BindgenContext, - ) -> TypeId; - - /// Create a named template type. - fn type_param( - with_id: Option, - location: clang::Cursor, - ctx: &mut BindgenContext, - ) -> Option; - - /// Create a builtin type. - fn builtin_type( - kind: TypeKind, - is_const: bool, - context: &mut BindgenContext, - ) -> TypeId; -} diff --git a/src/regex_set.rs b/src/regex_set.rs deleted file mode 100644 index 127c001829..0000000000 --- a/src/regex_set.rs +++ /dev/null @@ -1,92 +0,0 @@ -//! A type that represents the union of a set of regular expressions. - -use regex::RegexSet as RxSet; -use std::cell::Cell; - -/// A dynamic set of regular expressions. -#[derive(Debug, Default)] -pub 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`. - matched: Vec>, - set: Option, - /// Whether we should record matching items in the `matched` vector or not. - record_matches: bool, -} - -impl RegexSet { - /// Is this set empty? - pub fn is_empty(&self) -> bool { - self.items.is_empty() - } - - /// Insert a new regex into this set. - pub fn insert(&mut self, string: S) - where - S: AsRef, - { - self.items.push(string.as_ref().to_owned()); - self.matched.push(Cell::new(false)); - self.set = None; - } - - /// Returns slice of String from its field 'items' - pub fn get_items(&self) -> &[String] { - &self.items[..] - } - - /// Returns an iterator over regexes in the set which didn't match any - /// strings yet. - pub 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; - } - - Some(item) - }) - } - - /// Construct a RegexSet from the set of entries we've accumulated. - /// - /// Must be called before calling `matches()`, or it will always return - /// false. - pub fn build(&mut self, record_matches: bool) { - 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); - None - } - } - } - - /// Does the given `string` match any of the regexes in this set? - pub 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, - }; - - if !self.record_matches { - return set.is_match(s); - } - - let matches = set.matches(s); - if !matches.matched_any() { - return false; - } - for i in matches.iter() { - self.matched[i].set(true); - } - - true - } -} diff --git a/tests/expectations/Cargo.toml b/tests/expectations/Cargo.toml deleted file mode 100644 index c78cc09a0b..0000000000 --- a/tests/expectations/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "tests_expectations" -description = "bindgen results when ran on ../headers/*" -version = "0.1.0" -authors = [ - "Jyun-Yan You ", - "Emilio Cobos Álvarez ", - "The Servo project developers", -] - -[dependencies] -objc = "0.2" -block = "0.1" -libloading = "0.6.2" diff --git a/tests/expectations/build.rs b/tests/expectations/build.rs deleted file mode 100644 index beed7116a4..0000000000 --- a/tests/expectations/build.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! Generate a module with a custom `#[path=...]` for each of the files in our -//! libclang version-specific test expectations so that they get their layout -//! tests run. We need to do this because cargo doesn't automatically detect -//! tests subdirectories. - -use std::env; -use std::fs; -use std::io::Write; -use std::path::Path; - -const LIBCLANG_VERSION_DIRS: &'static [&'static str] = &[ - "libclang-4", - "libclang-5", - "libclang-9", -]; - -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - - let mut test_string = String::new(); - - for dir in LIBCLANG_VERSION_DIRS { - let dir = Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()) - .join("tests") - .join(dir); - - println!("cargo:rerun-if-changed={}", dir.display()); - - for entry in fs::read_dir(dir).unwrap() { - let entry = entry.unwrap(); - let path = entry.path(); - let path = path.canonicalize().unwrap_or_else(|_| path.into()); - if path.extension().map(|e| e.to_string_lossy()) != - Some("rs".into()) - { - continue; - } - - println!("cargo:rerun-if-changed={}", path.display()); - - let module_name: String = path - .display() - .to_string() - .chars() - .map(|c| match c { - 'a'..='z' | 'A'..='Z' | '0'..='9' => c, - _ => '_', - }) - .collect(); - - test_string.push_str(&format!( - r###" -#[path = "{}"] -mod {}; -"###, - path.display(), - module_name, - )); - } - } - - let out_path = Path::new(&env::var_os("OUT_DIR").unwrap()) - .join("libclang_version_specific_generated_tests.rs"); - let mut test_file = fs::File::create(out_path).unwrap(); - test_file.write_all(test_string.as_bytes()).unwrap(); -} diff --git a/tests/expectations/lib.rs b/tests/expectations/lib.rs deleted file mode 100755 index 562dc5548d..0000000000 --- a/tests/expectations/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![allow(dead_code)] -#![allow(non_camel_case_types)] -#![allow(non_upper_case_globals)] diff --git a/tests/expectations/tests/16-byte-alignment.rs b/tests/expectations/tests/16-byte-alignment.rs deleted file mode 100644 index 058568f24c..0000000000 --- a/tests/expectations/tests/16-byte-alignment.rs +++ /dev/null @@ -1,358 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -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(Copy, Clone)] -pub union rte_ipv4_tuple__bindgen_ty_1 { - pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, - pub sctp_tag: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!( - "Alignment of ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .dport as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(dport) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .sport as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(sport) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ipv4_tuple__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv4_tuple__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sctp_tag - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1), - "::", - stringify!(sctp_tag) - ) - ); -} -impl Default for rte_ipv4_tuple__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() - } - } -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_ipv4_tuple)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv4_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple), - "::", - stringify!(src_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_addr as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple), - "::", - stringify!(dst_addr) - ) - ); -} -impl Default for rte_ipv4_tuple { - 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(Copy, Clone)] -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(Copy, Clone)] -pub union rte_ipv6_tuple__bindgen_ty_1 { - pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, - pub sctp_tag: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!( - "Alignment of ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .dport as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(dport) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .sport as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(sport) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ipv6_tuple__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv6_tuple__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sctp_tag - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1), - "::", - stringify!(sctp_tag) - ) - ); -} -impl Default for rte_ipv6_tuple__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() - } - } -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_ipv6_tuple)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv6_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple), - "::", - stringify!(src_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_addr as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple), - "::", - stringify!(dst_addr) - ) - ); -} -impl Default for rte_ipv6_tuple { - 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)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub union rte_thash_tuple { - pub v4: rte_ipv4_tuple, - pub v6: rte_ipv6_tuple, -} -#[test] -fn bindgen_test_layout_rte_thash_tuple() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(rte_thash_tuple)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(rte_thash_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).v4 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_thash_tuple), - "::", - stringify!(v4) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).v6 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_thash_tuple), - "::", - stringify!(v6) - ) - ); -} -impl Default for rte_thash_tuple { - 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/tests/expectations/tests/16-byte-alignment_1_0.rs b/tests/expectations/tests/16-byte-alignment_1_0.rs deleted file mode 100644 index 1df6778b56..0000000000 --- a/tests/expectations/tests/16-byte-alignment_1_0.rs +++ /dev/null @@ -1,399 +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::new() - } -} -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, - 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!( - "Alignment of ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .dport as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(dport) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .sport as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ipv4_tuple__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv4_tuple__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sctp_tag - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple__bindgen_ty_1), - "::", - stringify!(sctp_tag) - ) - ); -} -impl Clone for rte_ipv4_tuple__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_ipv4_tuple)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv4_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple), - "::", - stringify!(src_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_addr as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv4_tuple), - "::", - stringify!(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, - 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!( - "Alignment of ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .dport as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(dport) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::( - ))) - .sport as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ipv6_tuple__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv6_tuple__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sctp_tag - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple__bindgen_ty_1), - "::", - stringify!(sctp_tag) - ) - ); -} -impl Clone for rte_ipv6_tuple__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_ipv6_tuple)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ipv6_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple), - "::", - stringify!(src_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_addr as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_ipv6_tuple), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(rte_thash_tuple)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).v4 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_thash_tuple), - "::", - stringify!(v4) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).v6 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_thash_tuple), - "::", - stringify!(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/tests/expectations/tests/381-decltype-alias.rs b/tests/expectations/tests/381-decltype-alias.rs deleted file mode 100644 index f4312a115a..0000000000 --- a/tests/expectations/tests/381-decltype-alias.rs +++ /dev/null @@ -1,13 +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 std_allocator_traits { - pub _address: u8, -} -pub type std_allocator_traits___size_type<_Alloc> = _Alloc; diff --git a/tests/expectations/tests/accessors.rs b/tests/expectations/tests/accessors.rs deleted file mode 100644 index 9977baa282..0000000000 --- a/tests/expectations/tests/accessors.rs +++ /dev/null @@ -1,422 +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 SomeAccessors { - pub mNoAccessor: ::std::os::raw::c_int, - ///
- pub mBothAccessors: ::std::os::raw::c_int, - ///
- pub mUnsafeAccessors: ::std::os::raw::c_int, - ///
- pub mImmutableAccessor: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_SomeAccessors() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(SomeAccessors)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SomeAccessors)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mNoAccessor as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SomeAccessors), - "::", - stringify!(mNoAccessor) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBothAccessors as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SomeAccessors), - "::", - stringify!(mBothAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mUnsafeAccessors - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SomeAccessors), - "::", - stringify!(mUnsafeAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mImmutableAccessor - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SomeAccessors), - "::", - stringify!(mImmutableAccessor) - ) - ); -} -impl SomeAccessors { - #[inline] - pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mBothAccessors - } - #[inline] - pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { - &mut self.mBothAccessors - } - #[inline] - pub unsafe fn get_mUnsafeAccessors(&self) -> &::std::os::raw::c_int { - &self.mUnsafeAccessors - } - #[inline] - pub unsafe fn get_mUnsafeAccessors_mut( - &mut self, - ) -> &mut ::std::os::raw::c_int { - &mut self.mUnsafeAccessors - } - #[inline] - pub fn get_mImmutableAccessor(&self) -> &::std::os::raw::c_int { - &self.mImmutableAccessor - } -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AllAccessors { - pub mBothAccessors: ::std::os::raw::c_int, - pub mAlsoBothAccessors: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_AllAccessors() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(AllAccessors)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(AllAccessors)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBothAccessors as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllAccessors), - "::", - stringify!(mBothAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mAlsoBothAccessors - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(AllAccessors), - "::", - stringify!(mAlsoBothAccessors) - ) - ); -} -impl AllAccessors { - #[inline] - pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mBothAccessors - } - #[inline] - pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { - &mut self.mBothAccessors - } - #[inline] - pub fn get_mAlsoBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mAlsoBothAccessors - } - #[inline] - pub fn get_mAlsoBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { - &mut self.mAlsoBothAccessors - } -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AllUnsafeAccessors { - pub mBothAccessors: ::std::os::raw::c_int, - pub mAlsoBothAccessors: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_AllUnsafeAccessors() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(AllUnsafeAccessors)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(AllUnsafeAccessors)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBothAccessors - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllUnsafeAccessors), - "::", - stringify!(mBothAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mAlsoBothAccessors - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(AllUnsafeAccessors), - "::", - stringify!(mAlsoBothAccessors) - ) - ); -} -impl AllUnsafeAccessors { - #[inline] - pub unsafe fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mBothAccessors - } - #[inline] - pub unsafe fn get_mBothAccessors_mut( - &mut self, - ) -> &mut ::std::os::raw::c_int { - &mut self.mBothAccessors - } - #[inline] - pub unsafe fn get_mAlsoBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mAlsoBothAccessors - } - #[inline] - pub unsafe fn get_mAlsoBothAccessors_mut( - &mut self, - ) -> &mut ::std::os::raw::c_int { - &mut self.mAlsoBothAccessors - } -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ContradictAccessors { - pub mBothAccessors: ::std::os::raw::c_int, - ///
- pub mNoAccessors: ::std::os::raw::c_int, - ///
- pub mUnsafeAccessors: ::std::os::raw::c_int, - ///
- pub mImmutableAccessor: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ContradictAccessors() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ContradictAccessors)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ContradictAccessors)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBothAccessors - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContradictAccessors), - "::", - stringify!(mBothAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mNoAccessors - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(ContradictAccessors), - "::", - stringify!(mNoAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mUnsafeAccessors - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ContradictAccessors), - "::", - stringify!(mUnsafeAccessors) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mImmutableAccessor - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(ContradictAccessors), - "::", - stringify!(mImmutableAccessor) - ) - ); -} -impl ContradictAccessors { - #[inline] - pub fn get_mBothAccessors(&self) -> &::std::os::raw::c_int { - &self.mBothAccessors - } - #[inline] - pub fn get_mBothAccessors_mut(&mut self) -> &mut ::std::os::raw::c_int { - &mut self.mBothAccessors - } - #[inline] - pub unsafe fn get_mUnsafeAccessors(&self) -> &::std::os::raw::c_int { - &self.mUnsafeAccessors - } - #[inline] - pub unsafe fn get_mUnsafeAccessors_mut( - &mut self, - ) -> &mut ::std::os::raw::c_int { - &mut self.mUnsafeAccessors - } - #[inline] - pub fn get_mImmutableAccessor(&self) -> &::std::os::raw::c_int { - &self.mImmutableAccessor - } -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Replaced { - pub mAccessor: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Replaced() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Replaced)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Replaced)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mAccessor as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Replaced), - "::", - stringify!(mAccessor) - ) - ); -} -impl Replaced { - #[inline] - pub fn get_mAccessor(&self) -> &::std::os::raw::c_int { - &self.mAccessor - } - #[inline] - pub fn get_mAccessor_mut(&mut self) -> &mut ::std::os::raw::c_int { - &mut self.mAccessor - } -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Wrapper { - pub mReplaced: Replaced, -} -#[test] -fn bindgen_test_layout_Wrapper() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Wrapper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Wrapper)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mReplaced as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Wrapper), - "::", - stringify!(mReplaced) - ) - ); -} -impl Wrapper { - #[inline] - pub fn get_mReplaced(&self) -> &Replaced { - &self.mReplaced - } - #[inline] - pub fn get_mReplaced_mut(&mut self) -> &mut Replaced { - &mut self.mReplaced - } -} diff --git a/tests/expectations/tests/allowlist-file.rs b/tests/expectations/tests/allowlist-file.rs deleted file mode 100644 index 2c2660a606..0000000000 --- a/tests/expectations/tests/allowlist-file.rs +++ /dev/null @@ -1,154 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const SOME_DEFUN: u32 = 123; -extern "C" { - #[link_name = "\u{1}_Z12SomeFunctionv"] - pub fn SomeFunction(); -} -extern "C" { - pub static mut someVar: ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct someClass { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_someClass() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(someClass)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(someClass)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN9someClass16somePublicMethodEi"] - pub fn someClass_somePublicMethod( - this: *mut someClass, - foo: ::std::os::raw::c_int, - ); -} -impl someClass { - #[inline] - pub unsafe fn somePublicMethod(&mut self, foo: ::std::os::raw::c_int) { - someClass_somePublicMethod(self, foo) - } -} -extern "C" { - pub fn ExternFunction(); -} -extern "C" { - #[link_name = "\u{1}_ZN3foo18NamespacedFunctionEv"] - pub fn foo_NamespacedFunction(); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct StructWithAllowlistedDefinition { - pub other: *mut StructWithAllowlistedFwdDecl, -} -#[test] -fn bindgen_test_layout_StructWithAllowlistedDefinition() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(StructWithAllowlistedDefinition)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(StructWithAllowlistedDefinition)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).other - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(StructWithAllowlistedDefinition), - "::", - stringify!(other) - ) - ); -} -impl Default for StructWithAllowlistedDefinition { - 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, Default, Copy, Clone)] -pub struct StructWithAllowlistedFwdDecl { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_StructWithAllowlistedFwdDecl() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(StructWithAllowlistedFwdDecl)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(StructWithAllowlistedFwdDecl)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(StructWithAllowlistedFwdDecl), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AllowlistMe { - pub foo: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_AllowlistMe() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AllowlistMe)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(AllowlistMe)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistMe), - "::", - stringify!(foo) - ) - ); -} diff --git a/tests/expectations/tests/allowlist-namespaces-basic.rs b/tests/expectations/tests/allowlist-namespaces-basic.rs deleted file mode 100644 index 36d03fefb5..0000000000 --- a/tests/expectations/tests/allowlist-namespaces-basic.rs +++ /dev/null @@ -1,38 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod outer { - #[allow(unused_imports)] - use self::super::super::root; - pub mod inner { - #[allow(unused_imports)] - use self::super::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Helper { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Helper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Helper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Helper)) - ); - } - } - } -} diff --git a/tests/expectations/tests/allowlist-namespaces.rs b/tests/expectations/tests/allowlist-namespaces.rs deleted file mode 100644 index 4236f63ed9..0000000000 --- a/tests/expectations/tests/allowlist-namespaces.rs +++ /dev/null @@ -1,68 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod outer { - #[allow(unused_imports)] - use self::super::super::root; - pub mod inner { - #[allow(unused_imports)] - use self::super::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Helper { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Helper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Helper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Helper)) - ); - } - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Test { - pub helper: root::outer::inner::Helper, - } - #[test] - fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).helper as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Test), - "::", - stringify!(helper) - ) - ); - } - } -} diff --git a/tests/expectations/tests/allowlist_fix.rs b/tests/expectations/tests/allowlist_fix.rs deleted file mode 100644 index 9cff795bd6..0000000000 --- a/tests/expectations/tests/allowlist_fix.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub enum Test {} - -extern "C" { - pub fn Servo_Test(a: *mut Test); -} diff --git a/tests/expectations/tests/allowlist_vars.rs b/tests/expectations/tests/allowlist_vars.rs deleted file mode 100644 index 590cbafcfa..0000000000 --- a/tests/expectations/tests/allowlist_vars.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const NONE: u32 = 0; -pub const FOO: u32 = 5; -pub const FOOB: i32 = -2; -pub const FOOBAR: i32 = -10; diff --git a/tests/expectations/tests/allowlisted-item-references-no-hash.rs b/tests/expectations/tests/allowlisted-item-references-no-hash.rs deleted file mode 100644 index bc3fde1ded..0000000000 --- a/tests/expectations/tests/allowlisted-item-references-no-hash.rs +++ /dev/null @@ -1,55 +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 NoHash { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_NoHash() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(NoHash)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(NoHash)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AllowlistMe { - pub a: NoHash, -} -#[test] -fn bindgen_test_layout_AllowlistMe() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(AllowlistMe)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AllowlistMe)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistMe), - "::", - stringify!(a) - ) - ); -} diff --git a/tests/expectations/tests/allowlisted-item-references-no-partialeq.rs b/tests/expectations/tests/allowlisted-item-references-no-partialeq.rs deleted file mode 100644 index f26f692391..0000000000 --- a/tests/expectations/tests/allowlisted-item-references-no-partialeq.rs +++ /dev/null @@ -1,55 +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 NoPartialEq { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_NoPartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(NoPartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(NoPartialEq)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AllowlistMe { - pub a: NoPartialEq, -} -#[test] -fn bindgen_test_layout_AllowlistMe() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(AllowlistMe)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AllowlistMe)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistMe), - "::", - stringify!(a) - ) - ); -} diff --git a/tests/expectations/tests/allowlisted_item_references_no_copy.rs b/tests/expectations/tests/allowlisted_item_references_no_copy.rs deleted file mode 100644 index a5cb17b238..0000000000 --- a/tests/expectations/tests/allowlisted_item_references_no_copy.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct NoCopy { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_NoCopy() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(NoCopy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(NoCopy)) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct AllowlistMe { - pub a: NoCopy, -} -#[test] -fn bindgen_test_layout_AllowlistMe() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(AllowlistMe)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AllowlistMe)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistMe), - "::", - stringify!(a) - ) - ); -} diff --git a/tests/expectations/tests/annotation_hide.rs b/tests/expectations/tests/annotation_hide.rs deleted file mode 100644 index 38435d0a4c..0000000000 --- a/tests/expectations/tests/annotation_hide.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct D { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_D() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(D)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(D)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct NotAnnotated { - pub f: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NotAnnotated() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NotAnnotated)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NotAnnotated)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).f as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NotAnnotated), - "::", - stringify!(f) - ) - ); -} diff --git a/tests/expectations/tests/anon-fields-prefix.rs b/tests/expectations/tests/anon-fields-prefix.rs deleted file mode 100644 index edd551d193..0000000000 --- a/tests/expectations/tests/anon-fields-prefix.rs +++ /dev/null @@ -1,159 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union color { - pub u1: color__bindgen_ty_1, - pub u2: color__bindgen_ty_2, - pub v3: [::std::os::raw::c_uchar; 3usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct color__bindgen_ty_1 { - pub r: ::std::os::raw::c_uchar, - pub g: ::std::os::raw::c_uchar, - pub b: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_color__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(color__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(color__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).r as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_1), - "::", - stringify!(r) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).g as *const _ - as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_1), - "::", - stringify!(g) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct color__bindgen_ty_2 { - pub y: ::std::os::raw::c_uchar, - pub u: ::std::os::raw::c_uchar, - pub v: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_color__bindgen_ty_2() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(color__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(color__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_2), - "::", - stringify!(y) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).u as *const _ - as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_2), - "::", - stringify!(u) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).v as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(color__bindgen_ty_2), - "::", - stringify!(v) - ) - ); -} -#[test] -fn bindgen_test_layout_color() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(color)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(color)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).v3 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(color), "::", stringify!(v3)) - ); -} -impl Default for color { - 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/tests/expectations/tests/anon_enum.rs b/tests/expectations/tests/anon_enum.rs deleted file mode 100644 index 8cae632999..0000000000 --- a/tests/expectations/tests/anon_enum.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialEq)] -pub struct Test { - pub foo: ::std::os::raw::c_int, - pub bar: f32, -} -pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Test__bindgen_ty_1 { - T_NONE = 0, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(bar)) - ); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Baz { - Foo = 0, - Bar = 1, -} diff --git a/tests/expectations/tests/anon_enum_allowlist.rs b/tests/expectations/tests/anon_enum_allowlist.rs deleted file mode 100644 index f0c06c5634..0000000000 --- a/tests/expectations/tests/anon_enum_allowlist.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const NODE_FLAG_FOO: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_FOO; -pub const NODE_FLAG_BAR: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_BAR; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - NODE_FLAG_FOO = 0, - NODE_FLAG_BAR = 1, -} diff --git a/tests/expectations/tests/anon_enum_trait.rs b/tests/expectations/tests/anon_enum_trait.rs deleted file mode 100644 index 9d6b8f574a..0000000000 --- a/tests/expectations/tests/anon_enum_trait.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct DataType { - pub _address: u8, -} -pub type DataType_value_type<_Tp> = _Tp; -pub type DataType_work_type<_Tp> = DataType_value_type<_Tp>; -pub type DataType_channel_type<_Tp> = DataType_value_type<_Tp>; -pub type DataType_vec_type<_Tp> = DataType_value_type<_Tp>; -pub const DataType_generic_type: DataType__bindgen_ty_1 = - DataType__bindgen_ty_1::generic_type; -pub const DataType_depth: DataType__bindgen_ty_1 = - DataType__bindgen_ty_1::generic_type; -pub const DataType_channels: DataType__bindgen_ty_1 = - DataType__bindgen_ty_1::generic_type; -pub const DataType_fmt: DataType__bindgen_ty_1 = - DataType__bindgen_ty_1::generic_type; -pub const DataType_type_: DataType__bindgen_ty_1 = - DataType__bindgen_ty_1::generic_type; -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum DataType__bindgen_ty_1 { - generic_type = 0, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Foo { - pub _address: u8, -} -pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; -pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo__bindgen_ty_1 { - Bar = 0, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/anon_struct_in_union.rs b/tests/expectations/tests/anon_struct_in_union.rs deleted file mode 100644 index 1a4040151e..0000000000 --- a/tests/expectations/tests/anon_struct_in_union.rs +++ /dev/null @@ -1,110 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct s { - pub u: s__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union s__bindgen_ty_1 { - pub field: s__bindgen_ty_1_inner, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s__bindgen_ty_1_inner)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s__bindgen_ty_1_inner)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(s__bindgen_ty_1_inner), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_s__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).field as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(s__bindgen_ty_1), - "::", - stringify!(field) - ) - ); -} -impl Default for s__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() - } - } -} -#[test] -fn bindgen_test_layout_s() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(s), "::", stringify!(u)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/anon_struct_in_union_1_0.rs b/tests/expectations/tests/anon_struct_in_union_1_0.rs deleted file mode 100644 index 021f41451b..0000000000 --- a/tests/expectations/tests/anon_struct_in_union_1_0.rs +++ /dev/null @@ -1,151 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s__bindgen_ty_1_inner)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s__bindgen_ty_1_inner)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(s__bindgen_ty_1_inner), - "::", - stringify!(b) - ) - ); -} -impl Clone for s__bindgen_ty_1_inner { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_s__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).field as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(s__bindgen_ty_1), - "::", - stringify!(field) - ) - ); -} -impl Clone for s__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_s() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(s)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(s)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(s), "::", stringify!(u)) - ); -} -impl Clone for s { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/anon_union.rs b/tests/expectations/tests/anon_union.rs deleted file mode 100644 index 8caf7d110d..0000000000 --- a/tests/expectations/tests/anon_union.rs +++ /dev/null @@ -1,101 +0,0 @@ -#![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, -} -impl TErrorResult_UnionState { - pub const 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)] -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, -} -#[test] -fn bindgen_test_layout_ErrorResult() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(ErrorResult)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ErrorResult)) - ); -} -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() - } - } -} -#[test] -fn __bindgen_test_layout_TErrorResult_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!( - "Size of template specialization: ", - stringify!(TErrorResult) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(TErrorResult) - ) - ); -} diff --git a/tests/expectations/tests/anon_union_1_0.rs b/tests/expectations/tests/anon_union_1_0.rs deleted file mode 100644 index 63273e608f..0000000000 --- a/tests/expectations/tests/anon_union_1_0.rs +++ /dev/null @@ -1,143 +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::new() - } -} -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, - concat!("Size of: ", stringify!(ErrorResult)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(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, - concat!( - "Size of template specialization: ", - stringify!(TErrorResult) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(TErrorResult) - ) - ); -} diff --git a/tests/expectations/tests/arg_keyword.rs b/tests/expectations/tests/arg_keyword.rs deleted file mode 100644 index 43ff58313d..0000000000 --- a/tests/expectations/tests/arg_keyword.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z3fooPKc"] - pub fn foo(type_: *const ::std::os::raw::c_char); -} diff --git a/tests/expectations/tests/array-of-zero-sized-types.rs b/tests/expectations/tests/array-of-zero-sized-types.rs deleted file mode 100644 index 0c00cea9ce..0000000000 --- a/tests/expectations/tests/array-of-zero-sized-types.rs +++ /dev/null @@ -1,59 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This should get an `_address` byte. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Empty { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Empty() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Empty)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Empty)) - ); -} -/// This should not get an `_address` byte, since each `Empty` gets one, meaning -/// that this object is addressable. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct HasArrayOfEmpty { - pub empties: [Empty; 10usize], -} -#[test] -fn bindgen_test_layout_HasArrayOfEmpty() { - assert_eq!( - ::std::mem::size_of::(), - 10usize, - concat!("Size of: ", stringify!(HasArrayOfEmpty)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(HasArrayOfEmpty)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).empties as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(HasArrayOfEmpty), - "::", - stringify!(empties) - ) - ); -} diff --git a/tests/expectations/tests/attribute_warn_unused_result.rs b/tests/expectations/tests/attribute_warn_unused_result.rs deleted file mode 100644 index 12d5eab04b..0000000000 --- a/tests/expectations/tests/attribute_warn_unused_result.rs +++ /dev/null @@ -1,48 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -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; -} -impl Foo { - #[inline] - #[must_use] - pub unsafe fn foo( - &mut self, - arg1: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int { - Foo_foo(self, arg1) - } -} -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/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs b/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs deleted file mode 100644 index d860acd1b4..0000000000 --- a/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs +++ /dev/null @@ -1,45 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -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/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs b/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs deleted file mode 100644 index d860acd1b4..0000000000 --- a/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs +++ /dev/null @@ -1,45 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -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/tests/expectations/tests/base-to-derived.rs b/tests/expectations/tests/base-to-derived.rs deleted file mode 100644 index 97830cd4fb..0000000000 --- a/tests/expectations/tests/base-to-derived.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 false_type { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_false_type() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(false_type)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(false_type)) - ); -} diff --git a/tests/expectations/tests/bindgen-union-inside-namespace.rs b/tests/expectations/tests/bindgen-union-inside-namespace.rs deleted file mode 100644 index 6083313bfb..0000000000 --- a/tests/expectations/tests/bindgen-union-inside-namespace.rs +++ /dev/null @@ -1,111 +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::new() - } - } - 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(foo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(bar) - ) - ); - } - impl Clone for Bar { - fn clone(&self) -> Self { - *self - } - } - } -} diff --git a/tests/expectations/tests/bitfield-32bit-overflow.rs b/tests/expectations/tests/bitfield-32bit-overflow.rs deleted file mode 100644 index 680b25d8fd..0000000000 --- a/tests/expectations/tests/bitfield-32bit-overflow.rs +++ /dev/null @@ -1,715 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct MuchBitfield { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 5usize]>, -} -#[test] -fn bindgen_test_layout_MuchBitfield() { - assert_eq!( - ::std::mem::size_of::(), - 5usize, - concat!("Size of: ", stringify!(MuchBitfield)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(MuchBitfield)) - ); -} -impl MuchBitfield { - #[inline] - pub fn m0(&self) -> ::std::os::raw::c_char { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) - } - } - #[inline] - pub fn set_m0(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m1(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m2(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m3(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m4(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m5(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m6(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m7(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m8(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m9(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m10(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m11(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m12(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m13(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m14(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m15(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m16(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m17(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m18(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m19(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m20(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m21(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m22(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m23(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m24(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m25(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m26(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m27(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m28(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m29(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m30(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m31(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m32(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(32usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - m0: ::std::os::raw::c_char, - m1: ::std::os::raw::c_char, - m2: ::std::os::raw::c_char, - m3: ::std::os::raw::c_char, - m4: ::std::os::raw::c_char, - m5: ::std::os::raw::c_char, - m6: ::std::os::raw::c_char, - m7: ::std::os::raw::c_char, - m8: ::std::os::raw::c_char, - m9: ::std::os::raw::c_char, - m10: ::std::os::raw::c_char, - m11: ::std::os::raw::c_char, - m12: ::std::os::raw::c_char, - m13: ::std::os::raw::c_char, - m14: ::std::os::raw::c_char, - m15: ::std::os::raw::c_char, - m16: ::std::os::raw::c_char, - m17: ::std::os::raw::c_char, - m18: ::std::os::raw::c_char, - m19: ::std::os::raw::c_char, - m20: ::std::os::raw::c_char, - m21: ::std::os::raw::c_char, - m22: ::std::os::raw::c_char, - m23: ::std::os::raw::c_char, - m24: ::std::os::raw::c_char, - m25: ::std::os::raw::c_char, - m26: ::std::os::raw::c_char, - m27: ::std::os::raw::c_char, - m28: ::std::os::raw::c_char, - m29: ::std::os::raw::c_char, - m30: ::std::os::raw::c_char, - m31: ::std::os::raw::c_char, - m32: ::std::os::raw::c_char, - ) -> __BindgenBitfieldUnit<[u8; 5usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let m0: u8 = unsafe { ::std::mem::transmute(m0) }; - m0 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let m1: u8 = unsafe { ::std::mem::transmute(m1) }; - m1 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let m2: u8 = unsafe { ::std::mem::transmute(m2) }; - m2 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let m3: u8 = unsafe { ::std::mem::transmute(m3) }; - m3 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let m4: u8 = unsafe { ::std::mem::transmute(m4) }; - m4 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let m5: u8 = unsafe { ::std::mem::transmute(m5) }; - m5 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let m6: u8 = unsafe { ::std::mem::transmute(m6) }; - m6 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let m7: u8 = unsafe { ::std::mem::transmute(m7) }; - m7 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let m8: u8 = unsafe { ::std::mem::transmute(m8) }; - m8 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let m9: u8 = unsafe { ::std::mem::transmute(m9) }; - m9 as u64 - }); - __bindgen_bitfield_unit.set(10usize, 1u8, { - let m10: u8 = unsafe { ::std::mem::transmute(m10) }; - m10 as u64 - }); - __bindgen_bitfield_unit.set(11usize, 1u8, { - let m11: u8 = unsafe { ::std::mem::transmute(m11) }; - m11 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 1u8, { - let m12: u8 = unsafe { ::std::mem::transmute(m12) }; - m12 as u64 - }); - __bindgen_bitfield_unit.set(13usize, 1u8, { - let m13: u8 = unsafe { ::std::mem::transmute(m13) }; - m13 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 1u8, { - let m14: u8 = unsafe { ::std::mem::transmute(m14) }; - m14 as u64 - }); - __bindgen_bitfield_unit.set(15usize, 1u8, { - let m15: u8 = unsafe { ::std::mem::transmute(m15) }; - m15 as u64 - }); - __bindgen_bitfield_unit.set(16usize, 1u8, { - let m16: u8 = unsafe { ::std::mem::transmute(m16) }; - m16 as u64 - }); - __bindgen_bitfield_unit.set(17usize, 1u8, { - let m17: u8 = unsafe { ::std::mem::transmute(m17) }; - m17 as u64 - }); - __bindgen_bitfield_unit.set(18usize, 1u8, { - let m18: u8 = unsafe { ::std::mem::transmute(m18) }; - m18 as u64 - }); - __bindgen_bitfield_unit.set(19usize, 1u8, { - let m19: u8 = unsafe { ::std::mem::transmute(m19) }; - m19 as u64 - }); - __bindgen_bitfield_unit.set(20usize, 1u8, { - let m20: u8 = unsafe { ::std::mem::transmute(m20) }; - m20 as u64 - }); - __bindgen_bitfield_unit.set(21usize, 1u8, { - let m21: u8 = unsafe { ::std::mem::transmute(m21) }; - m21 as u64 - }); - __bindgen_bitfield_unit.set(22usize, 1u8, { - let m22: u8 = unsafe { ::std::mem::transmute(m22) }; - m22 as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let m23: u8 = unsafe { ::std::mem::transmute(m23) }; - m23 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 1u8, { - let m24: u8 = unsafe { ::std::mem::transmute(m24) }; - m24 as u64 - }); - __bindgen_bitfield_unit.set(25usize, 1u8, { - let m25: u8 = unsafe { ::std::mem::transmute(m25) }; - m25 as u64 - }); - __bindgen_bitfield_unit.set(26usize, 1u8, { - let m26: u8 = unsafe { ::std::mem::transmute(m26) }; - m26 as u64 - }); - __bindgen_bitfield_unit.set(27usize, 1u8, { - let m27: u8 = unsafe { ::std::mem::transmute(m27) }; - m27 as u64 - }); - __bindgen_bitfield_unit.set(28usize, 1u8, { - let m28: u8 = unsafe { ::std::mem::transmute(m28) }; - m28 as u64 - }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let m29: u8 = unsafe { ::std::mem::transmute(m29) }; - m29 as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let m30: u8 = unsafe { ::std::mem::transmute(m30) }; - m30 as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let m31: u8 = unsafe { ::std::mem::transmute(m31) }; - m31 as u64 - }); - __bindgen_bitfield_unit.set(32usize, 1u8, { - let m32: u8 = unsafe { ::std::mem::transmute(m32) }; - m32 as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield-large.rs b/tests/expectations/tests/bitfield-large.rs deleted file mode 100644 index b2c353a221..0000000000 --- a/tests/expectations/tests/bitfield-large.rs +++ /dev/null @@ -1,203 +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 const 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)] -#[repr(align(16))] -#[derive(Debug, Default, Copy, Clone)] -pub struct HasBigBitfield { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, -} -#[test] -fn bindgen_test_layout_HasBigBitfield() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(HasBigBitfield)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(HasBigBitfield)) - ); -} -impl HasBigBitfield { - #[inline] - pub fn x(&self) -> i128 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 128u8) as u128) - } - } - #[inline] - pub fn set_x(&mut self, val: i128) { - unsafe { - let val: u128 = ::std::mem::transmute(val); - self._bitfield_1.set(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.set(0usize, 128u8, { - let x: u128 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(16))] -#[derive(Debug, Default, Copy, Clone)] -pub struct HasTwoBigBitfields { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, -} -#[test] -fn bindgen_test_layout_HasTwoBigBitfields() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(HasTwoBigBitfields)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(HasTwoBigBitfields)) - ); -} -impl HasTwoBigBitfields { - #[inline] - pub fn x(&self) -> i128 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 80u8) as u128) - } - } - #[inline] - pub fn set_x(&mut self, val: i128) { - unsafe { - let val: u128 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 80u8, val as u64) - } - } - #[inline] - pub fn y(&self) -> i128 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(80usize, 48u8) as u128) - } - } - #[inline] - pub fn set_y(&mut self, val: i128) { - unsafe { - let val: u128 = ::std::mem::transmute(val); - self._bitfield_1.set(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.set(0usize, 80u8, { - let x: u128 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); - __bindgen_bitfield_unit.set(80usize, 48u8, { - let y: u128 = unsafe { ::std::mem::transmute(y) }; - y as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield-linux-32.rs b/tests/expectations/tests/bitfield-linux-32.rs deleted file mode 100644 index 15c35cee8d..0000000000 --- a/tests/expectations/tests/bitfield-linux-32.rs +++ /dev/null @@ -1,163 +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 const 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, packed(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Test { - pub foo: u64, - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(foo)) - ); -} -impl Test { - #[inline] - pub fn x(&self) -> u64 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 56u8) as u64) - } - } - #[inline] - pub fn set_x(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 56u8, val as u64) - } - } - #[inline] - pub fn y(&self) -> u64 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(56usize, 8u8) as u64) - } - } - #[inline] - pub fn set_y(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(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.set(0usize, 56u8, { - let x: u64 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); - __bindgen_bitfield_unit.set(56usize, 8u8, { - let y: u64 = unsafe { ::std::mem::transmute(y) }; - y as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield-method-same-name.rs b/tests/expectations/tests/bitfield-method-same-name.rs deleted file mode 100644 index e9c1a76d1c..0000000000 --- a/tests/expectations/tests/bitfield-method-same-name.rs +++ /dev/null @@ -1,164 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo4typeEv"] - pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; -} -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" { - #[link_name = "\u{1}_ZN3Foo8set_typeEc"] - pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); -} -impl Foo { - #[inline] - pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) - } - } - #[inline] - pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 3u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - type__bindgen_bitfield: ::std::os::raw::c_char, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let type__bindgen_bitfield: u8 = - unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; - type__bindgen_bitfield as u64 - }); - __bindgen_bitfield_unit - } - #[inline] - pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { - Foo_type(self) - } - #[inline] - pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_char) { - Foo_set_type_(self, c) - } - #[inline] - pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_char) { - Foo_set_type(self, c) - } -} diff --git a/tests/expectations/tests/bitfield_align.rs b/tests/expectations/tests/bitfield_align.rs deleted file mode 100644 index 509981a887..0000000000 --- a/tests/expectations/tests/bitfield_align.rs +++ /dev/null @@ -1,788 +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 const 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)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - 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, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::
(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(x)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).y as *const _ as usize }, - 3usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(y)) - ); -} -impl A { - #[inline] - pub fn b1(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) - } - } - #[inline] - pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b3(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b4(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b5(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b6(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b7(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b8(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b9(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b10(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(9usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - b1: ::std::os::raw::c_uint, - b2: ::std::os::raw::c_uint, - b3: ::std::os::raw::c_uint, - b4: ::std::os::raw::c_uint, - b5: ::std::os::raw::c_uint, - b6: ::std::os::raw::c_uint, - b7: ::std::os::raw::c_uint, - b8: ::std::os::raw::c_uint, - b9: ::std::os::raw::c_uint, - b10: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let b1: u32 = unsafe { ::std::mem::transmute(b1) }; - b1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b2: u32 = unsafe { ::std::mem::transmute(b2) }; - b2 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let b3: u32 = unsafe { ::std::mem::transmute(b3) }; - b3 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let b4: u32 = unsafe { ::std::mem::transmute(b4) }; - b4 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let b5: u32 = unsafe { ::std::mem::transmute(b5) }; - b5 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let b6: u32 = unsafe { ::std::mem::transmute(b6) }; - b6 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let b7: u32 = unsafe { ::std::mem::transmute(b7) }; - b7 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let b8: u32 = unsafe { ::std::mem::transmute(b8) }; - b8 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let b9: u32 = unsafe { ::std::mem::transmute(b9) }; - b9 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let b10: u32 = unsafe { ::std::mem::transmute(b10) }; - b10 as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct B { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B)) - ); -} -impl B { - #[inline] - pub fn foo(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.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.set(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) - } - } - #[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) - } - } - #[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(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, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(x)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(baz)) - ); -} -impl C { - #[inline] - pub fn b1(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) - } - } - #[inline] - pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(1usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - b1: ::std::os::raw::c_uint, - b2: ::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 b1: u32 = unsafe { ::std::mem::transmute(b1) }; - b1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b2: u32 = unsafe { ::std::mem::transmute(b2) }; - b2 as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Date1 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, - pub __bindgen_padding_0: u8, -} -#[test] -fn bindgen_test_layout_Date1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Date1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(Date1)) - ); -} -impl Date1 { - #[inline] - pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) - } - } - #[inline] - pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(16usize, 8u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - nWeekDay: ::std::os::raw::c_ushort, - nMonthDay: ::std::os::raw::c_ushort, - nMonth: ::std::os::raw::c_ushort, - nYear: ::std::os::raw::c_ushort, - ) -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Date2 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_Date2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Date2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(Date2)) - ); -} -impl Date2 { - #[inline] - pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) - } - } - #[inline] - pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_byte(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(24usize, 8u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - nWeekDay: ::std::os::raw::c_ushort, - nMonthDay: ::std::os::raw::c_ushort, - nMonth: ::std::os::raw::c_ushort, - nYear: ::std::os::raw::c_ushort, - byte: ::std::os::raw::c_uchar, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let byte: u8 = unsafe { ::std::mem::transmute(byte) }; - byte as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Date3 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, - pub byte: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_Date3() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Date3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(Date3)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).byte as *const _ as usize }, - 3usize, - concat!( - "Offset of field: ", - stringify!(Date3), - "::", - stringify!(byte) - ) - ); -} -impl Date3 { - #[inline] - pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) - } - } - #[inline] - pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(16usize, 8u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - nWeekDay: ::std::os::raw::c_ushort, - nMonthDay: ::std::os::raw::c_ushort, - nMonth: ::std::os::raw::c_ushort, - nYear: ::std::os::raw::c_ushort, - ) -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield_align_2.rs b/tests/expectations/tests/bitfield_align_2.rs deleted file mode 100644 index 1a1f7dd822..0000000000 --- a/tests/expectations/tests/bitfield_align_2.rs +++ /dev/null @@ -1,175 +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 const 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(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum MyEnum { - ONE = 0, - TWO = 1, - THREE = 2, - FOUR = 3, -} -#[repr(C)] -#[repr(align(8))] -#[derive(Debug, Copy, Clone)] -pub struct TaggedPtr { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, -} -#[test] -fn bindgen_test_layout_TaggedPtr() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(TaggedPtr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(TaggedPtr)) - ); -} -impl Default for TaggedPtr { - 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 TaggedPtr { - #[inline] - pub fn tag(&self) -> MyEnum { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 2u8) as u32) - } - } - #[inline] - pub fn set_tag(&mut self, val: MyEnum) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_ptr(&mut self, val: ::std::os::raw::c_long) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(2usize, 62u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - tag: MyEnum, - ptr: ::std::os::raw::c_long, - ) -> __BindgenBitfieldUnit<[u8; 8usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 2u8, { - let tag: u32 = unsafe { ::std::mem::transmute(tag) }; - tag as u64 - }); - __bindgen_bitfield_unit.set(2usize, 62u8, { - let ptr: u64 = unsafe { ::std::mem::transmute(ptr) }; - ptr as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield_large_overflow.rs b/tests/expectations/tests/bitfield_large_overflow.rs deleted file mode 100644 index 4ee1f59844..0000000000 --- a/tests/expectations/tests/bitfield_large_overflow.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct _bindgen_ty_1 { - pub _bindgen_opaque_blob: [u64; 10usize], -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1>(), - 80usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); -} -extern "C" { - pub static mut a: _bindgen_ty_1; -} diff --git a/tests/expectations/tests/bitfield_method_mangling.rs b/tests/expectations/tests/bitfield_method_mangling.rs deleted file mode 100644 index 42fa3c4cb4..0000000000 --- a/tests/expectations/tests/bitfield_method_mangling.rs +++ /dev/null @@ -1,158 +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 const 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)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct mach_msg_type_descriptor_t { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_mach_msg_type_descriptor_t() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(mach_msg_type_descriptor_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(mach_msg_type_descriptor_t)) - ); -} -impl mach_msg_type_descriptor_t { - #[inline] - pub fn pad3(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 24u8) as u32) - } - } - #[inline] - pub fn set_pad3(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_type(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(24usize, 8u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - pad3: ::std::os::raw::c_uint, - type_: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 24u8, { - let pad3: u32 = unsafe { ::std::mem::transmute(pad3) }; - pad3 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let type_: u32 = unsafe { ::std::mem::transmute(type_) }; - type_ as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/bitfield_pragma_packed.rs b/tests/expectations/tests/bitfield_pragma_packed.rs deleted file mode 100644 index 27cd90f140..0000000000 --- a/tests/expectations/tests/bitfield_pragma_packed.rs +++ /dev/null @@ -1,211 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Struct { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_Struct() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Struct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Struct)) - ); -} -impl Struct { - #[inline] - pub fn a(&self) -> ::std::os::raw::c_uchar { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_c(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_e(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(24usize, 8u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - a: ::std::os::raw::c_uchar, - b: ::std::os::raw::c_uchar, - c: ::std::os::raw::c_uchar, - d: ::std::os::raw::c_ushort, - e: ::std::os::raw::c_uchar, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u8 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b: u8 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit.set(2usize, 6u8, { - let c: u8 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }); - __bindgen_bitfield_unit.set(8usize, 16u8, { - let d: u16 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let e: u8 = unsafe { ::std::mem::transmute(e) }; - e as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/block_return_type.rs b/tests/expectations/tests/block_return_type.rs deleted file mode 100644 index bc4347335e..0000000000 --- a/tests/expectations/tests/block_return_type.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -extern crate block; -extern "C" { - pub fn func() -> _bindgen_ty_id_4; -} -pub type _bindgen_ty_id_4 = *const ::block::Block< - (::std::os::raw::c_int, ::std::os::raw::c_int), - ::std::os::raw::c_int, ->; diff --git a/tests/expectations/tests/blocklist-and-impl-debug.rs b/tests/expectations/tests/blocklist-and-impl-debug.rs deleted file mode 100644 index ba39fb14d5..0000000000 --- a/tests/expectations/tests/blocklist-and-impl-debug.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub struct BlocklistMe(u8); - -/// Because this type contains a blocklisted type, it should not derive Debug. -#[repr(C)] -pub struct ShouldManuallyImplDebug { - pub a: BlocklistMe, -} -#[test] -fn bindgen_test_layout_ShouldManuallyImplDebug() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ShouldManuallyImplDebug)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ShouldManuallyImplDebug)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldManuallyImplDebug), - "::", - stringify!(a) - ) - ); -} -impl Default for ShouldManuallyImplDebug { - 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 ShouldManuallyImplDebug { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "ShouldManuallyImplDebug {{ }}") - } -} diff --git a/tests/expectations/tests/blocklist-file.rs b/tests/expectations/tests/blocklist-file.rs deleted file mode 100644 index fe00b5ab4a..0000000000 --- a/tests/expectations/tests/blocklist-file.rs +++ /dev/null @@ -1,94 +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 SizedIntegers { - pub x: u8, - pub y: u16, - pub z: u32, -} -#[test] -fn bindgen_test_layout_SizedIntegers() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SizedIntegers)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SizedIntegers)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SizedIntegers), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(SizedIntegers), - "::", - stringify!(y) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).z as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SizedIntegers), - "::", - stringify!(z) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct StructWithBlocklistedFwdDecl { - pub b: u8, -} -#[test] -fn bindgen_test_layout_StructWithBlocklistedFwdDecl() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(StructWithBlocklistedFwdDecl)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(StructWithBlocklistedFwdDecl)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(StructWithBlocklistedFwdDecl), - "::", - stringify!(b) - ) - ); -} diff --git a/tests/expectations/tests/blocklist-function.rs b/tests/expectations/tests/blocklist-function.rs deleted file mode 100644 index 5299b1517e..0000000000 --- a/tests/expectations/tests/blocklist-function.rs +++ /dev/null @@ -1,42 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - } - pub mod bar { - #[allow(unused_imports)] - use self::super::super::root; - extern "C" { - #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"] - pub fn NamespacedFunction(); - } - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct C { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(C)) - ); - } -} diff --git a/tests/expectations/tests/blocks-signature.rs b/tests/expectations/tests/blocks-signature.rs deleted file mode 100644 index 22136ddfb7..0000000000 --- a/tests/expectations/tests/blocks-signature.rs +++ /dev/null @@ -1,101 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -extern crate block; -pub type size_t = ::std::os::raw::c_ulonglong; -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" { - #[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" { - #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] - pub fn foo(arg1: _bindgen_ty_id_50) -> bool; -} -extern "C" { - #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] - pub fn foo_ptr(arg1: *mut _bindgen_ty_id_56) -> bool; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct contains_block_pointers { - pub val: contains_block_pointers__bindgen_ty_id_61, - pub ptr_val: *mut _bindgen_ty_id_68, -} -#[test] -fn bindgen_test_layout_contains_block_pointers() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(contains_block_pointers)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(contains_block_pointers)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).val as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(contains_block_pointers), - "::", - stringify!(val) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ptr_val - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(contains_block_pointers), - "::", - stringify!(ptr_val) - ) - ); -} -impl Default for contains_block_pointers { - 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 type _bindgen_ty_id_33 = *const ::block::Block<(), ()>; -pub type _bindgen_ty_id_40 = *const ::block::Block< - ( - dispatch_data_t, - size_t, - *const ::std::os::raw::c_void, - size_t, - ), - bool, ->; -pub type _bindgen_ty_id_50 = *const ::block::Block<(size_t,), ()>; -pub type _bindgen_ty_id_56 = *const ::block::Block<(size_t,), ()>; -pub type contains_block_pointers__bindgen_ty_id_61 = - *const ::block::Block<(::std::os::raw::c_int,), ()>; -pub type _bindgen_ty_id_68 = - *const ::block::Block<(::std::os::raw::c_int,), ()>; diff --git a/tests/expectations/tests/blocks.rs b/tests/expectations/tests/blocks.rs deleted file mode 100644 index b2ae0b2901..0000000000 --- a/tests/expectations/tests/blocks.rs +++ /dev/null @@ -1,84 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -pub type size_t = ::std::os::raw::c_ulonglong; -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" { - #[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" { - #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] - pub fn foo(arg1: *mut ::std::os::raw::c_void) -> bool; -} -extern "C" { - #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] - pub fn foo_ptr(arg1: *mut *mut ::std::os::raw::c_void) -> bool; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct contains_block_pointers { - pub val: *mut ::std::os::raw::c_void, - pub ptr_val: *mut *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_contains_block_pointers() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(contains_block_pointers)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(contains_block_pointers)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).val as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(contains_block_pointers), - "::", - stringify!(val) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ptr_val - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(contains_block_pointers), - "::", - stringify!(ptr_val) - ) - ); -} -impl Default for contains_block_pointers { - 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/tests/expectations/tests/bug-1529681.rs b/tests/expectations/tests/bug-1529681.rs deleted file mode 100644 index 6a0f5e134a..0000000000 --- a/tests/expectations/tests/bug-1529681.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 BrowsingContext { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_BrowsingContext() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(BrowsingContext)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(BrowsingContext)) - ); -} diff --git a/tests/expectations/tests/builtin-template.rs b/tests/expectations/tests/builtin-template.rs deleted file mode 100644 index 112b767008..0000000000 --- a/tests/expectations/tests/builtin-template.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type std_make_integer_sequence = u8; diff --git a/tests/expectations/tests/c-empty-layout.rs b/tests/expectations/tests/c-empty-layout.rs deleted file mode 100644 index ebef2b6d82..0000000000 --- a/tests/expectations/tests/c-empty-layout.rs +++ /dev/null @@ -1,23 +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 {} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/c_naming.rs b/tests/expectations/tests/c_naming.rs deleted file mode 100644 index abcccf1fd2..0000000000 --- a/tests/expectations/tests/c_naming.rs +++ /dev/null @@ -1,96 +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 struct_a { - pub a: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_struct_a() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(struct_a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(struct_a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(struct_a), - "::", - stringify!(a) - ) - ); -} -pub type a = *const struct_a; -#[repr(C)] -#[derive(Copy, Clone)] -pub union union_b { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_union_b() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(union_b)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(union_b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(union_b), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(union_b), - "::", - stringify!(b) - ) - ); -} -impl Default for union_b { - 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 type b = union_b; -pub const enum_c_A: enum_c = 0; -pub type enum_c = ::std::os::raw::c_uint; -extern "C" { - pub fn takes_a(arg: a); -} -extern "C" { - pub fn takes_b(arg: b); -} -extern "C" { - pub fn takes_c(arg: enum_c); -} diff --git a/tests/expectations/tests/call-conv-typedef.rs b/tests/expectations/tests/call-conv-typedef.rs deleted file mode 100644 index 6eabb1f6ad..0000000000 --- a/tests/expectations/tests/call-conv-typedef.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(not(test))] - -pub type void_fn = ::std::option::Option; -pub type fn_ = ::std::option::Option< - unsafe extern "stdcall" fn(id: ::std::os::raw::c_int) -> void_fn, ->; diff --git a/tests/expectations/tests/canonical-types.rs b/tests/expectations/tests/canonical-types.rs deleted file mode 100644 index 80d7fec374..0000000000 --- a/tests/expectations/tests/canonical-types.rs +++ /dev/null @@ -1,278 +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 ClassA { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ClassA_ClassAInner { - pub x: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ClassA_ClassAInner { - 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, Default, Copy, Clone)] -pub struct ClassB { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ClassC { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ClassC_ClassCInnerB { - pub cache: *mut ClassC_ClassCInnerA, -} -impl Default for ClassC_ClassCInnerB { - 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 ClassC_ClassCInnerA { - pub member: *mut ClassC_ClassCInnerB, -} -impl Default for ClassC_ClassCInnerA { - 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 ClassC_ClassCInnerCRTP { - pub _address: u8, -} -impl Default for ClassC_ClassCInnerCRTP { - 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 ClassD { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_ClassD() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ClassD)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ClassD)) - ); -} -impl Default for ClassD { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_ClassB_open0_ClassD_ClassCInnerCRTP_close0_instantiation( -) { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(ClassB)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(ClassB)) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ClassCInnerCRTP { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_ClassCInnerCRTP() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ClassCInnerCRTP)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ClassCInnerCRTP)) - ); -} -impl Default for ClassCInnerCRTP { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_ClassB_open0_ClassCInnerCRTP_ClassAInner_close0_instantiation( -) { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(ClassB)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(ClassB)) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ClassAInner { - pub x: *mut ClassCInnerA, -} -#[test] -fn bindgen_test_layout_ClassAInner() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ClassAInner)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ClassAInner)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ClassAInner), - "::", - stringify!(x) - ) - ); -} -impl Default for ClassAInner { - 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 ClassCInnerA { - pub member: *mut ClassCInnerB, -} -#[test] -fn bindgen_test_layout_ClassCInnerA() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ClassCInnerA)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ClassCInnerA)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).member as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ClassCInnerA), - "::", - stringify!(member) - ) - ); -} -impl Default for ClassCInnerA { - 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 ClassCInnerB { - pub cache: *mut ClassCInnerA, -} -#[test] -fn bindgen_test_layout_ClassCInnerB() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ClassCInnerB)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ClassCInnerB)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cache as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ClassCInnerB), - "::", - stringify!(cache) - ) - ); -} -impl Default for ClassCInnerB { - 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/tests/expectations/tests/canonical_path_without_namespacing.rs b/tests/expectations/tests/canonical_path_without_namespacing.rs deleted file mode 100644 index 12f10a8873..0000000000 --- a/tests/expectations/tests/canonical_path_without_namespacing.rs +++ /dev/null @@ -1,29 +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 Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} -extern "C" { - #[link_name = "\u{1}_Z3bazPN3foo3BarE"] - pub fn baz(arg1: *mut Bar); -} diff --git a/tests/expectations/tests/char.rs b/tests/expectations/tests/char.rs deleted file mode 100644 index 1e1a19879d..0000000000 --- a/tests/expectations/tests/char.rs +++ /dev/null @@ -1,104 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Char = ::std::os::raw::c_char; -pub type SChar = ::std::os::raw::c_schar; -pub type UChar = ::std::os::raw::c_uchar; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Test { - pub ch: ::std::os::raw::c_char, - pub u: ::std::os::raw::c_uchar, - pub d: ::std::os::raw::c_schar, - pub cch: ::std::os::raw::c_char, - pub cu: ::std::os::raw::c_uchar, - pub cd: ::std::os::raw::c_schar, - pub Cch: Char, - pub Cu: UChar, - pub Cd: SChar, - pub Ccch: Char, - pub Ccu: UChar, - pub Ccd: SChar, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ch as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(ch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 1usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(u)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 2usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cch as *const _ as usize }, - 3usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cu as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cd as *const _ as usize }, - 5usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cch as *const _ as usize }, - 6usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cu as *const _ as usize }, - 7usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cd as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccch as *const _ as usize }, - 9usize, - concat!( - "Offset of field: ", - stringify!(Test), - "::", - stringify!(Ccch) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccu as *const _ as usize }, - 10usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccd as *const _ as usize }, - 11usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccd)) - ); -} diff --git a/tests/expectations/tests/class.rs b/tests/expectations/tests/class.rs deleted file mode 100644 index 3d3afb1926..0000000000 --- a/tests/expectations/tests/class.rs +++ /dev/null @@ -1,496 +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 const 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)] -#[derive(Copy, Clone)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).big_array as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(big_array) - ) - ); -} -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() - } - } -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(zero_length_array) - ) - ); -} -impl Default for C_with_zero_length_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array)) - ); -} -impl Default for C_with_incomplete_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) - ); -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); -} -impl Default for C_with_zero_length_array_and_incomplete_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - ::std::mem::align_of::( - ), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithDtor)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithDtor), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -pub struct IncompleteArrayNonCopiable { - pub whatever: *mut ::std::os::raw::c_void, - pub incomplete_array: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) - ); -} -impl Default for IncompleteArrayNonCopiable { - 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(Copy, Clone)] -pub union Union { - pub d: f32, - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Union() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Union)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Union)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(i)) - ); -} -impl Default for 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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct WithUnion { - pub data: Union, -} -#[test] -fn bindgen_test_layout_WithUnion() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithUnion), - "::", - stringify!(data) - ) - ); -} -impl Default for WithUnion { - 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, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct RealAbstractionWithTonsOfMethods { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(RealAbstractionWithTonsOfMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(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 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/tests/expectations/tests/class_1_0.rs b/tests/expectations/tests/class_1_0.rs deleted file mode 100644 index 3f948bb138..0000000000 --- a/tests/expectations/tests/class_1_0.rs +++ /dev/null @@ -1,547 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).big_array as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) - ); -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_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() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - ::std::mem::align_of::( - ), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Hash, PartialEq, Eq)] -pub struct WithDtor { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_WithDtor() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithDtor)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithDtor), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -pub struct IncompleteArrayNonCopiable { - pub whatever: *mut ::std::os::raw::c_void, - pub incomplete_array: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) - ); -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Union)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Union)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithUnion), - "::", - stringify!(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, - concat!("Size of: ", stringify!(RealAbstractionWithTonsOfMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(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/tests/expectations/tests/class_nested.rs b/tests/expectations/tests/class_nested.rs deleted file mode 100644 index ecc5c20a7e..0000000000 --- a/tests/expectations/tests/class_nested.rs +++ /dev/null @@ -1,181 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct A { - pub member_a: ::std::os::raw::c_int, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct A_B { - pub member_b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A_B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A_B)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).member_b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A_B), - "::", - stringify!(member_b) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct A_D { - pub foo: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for A_D { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member_a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A), - "::", - stringify!(member_a) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct A_C { - pub baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A_C() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A_C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A_C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A_C), "::", stringify!(baz)) - ); -} -extern "C" { - pub static mut var: A_B; -} -#[test] -fn __bindgen_test_layout_A_D_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(A_D<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(A_D<::std::os::raw::c_int>) - ) - ); -} -extern "C" { - pub static mut baz: A_D<::std::os::raw::c_int>; -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct D { - pub member: A_B, -} -#[test] -fn bindgen_test_layout_D() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(D)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(D)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(D), "::", stringify!(member)) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Templated { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Templated_Templated_inner { - pub member_ptr: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Templated_Templated_inner { - 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 Templated { - 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/tests/expectations/tests/class_no_members.rs b/tests/expectations/tests/class_no_members.rs deleted file mode 100644 index 6c1e4880a6..0000000000 --- a/tests/expectations/tests/class_no_members.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct whatever { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_whatever() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(whatever)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(whatever)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct whatever_child { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_whatever_child() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(whatever_child)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(whatever_child)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct whatever_child_with_member { - pub m_member: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_whatever_child_with_member() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(whatever_child_with_member)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(whatever_child_with_member)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).m_member - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(whatever_child_with_member), - "::", - stringify!(m_member) - ) - ); -} diff --git a/tests/expectations/tests/class_static.rs b/tests/expectations/tests/class_static.rs deleted file mode 100644 index 2388f3b3a4..0000000000 --- a/tests/expectations/tests/class_static.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct MyClass { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN7MyClass7exampleE"] - pub static mut MyClass_example: *const ::std::os::raw::c_int; -} -extern "C" { - #[link_name = "\u{1}_ZN7MyClass26example_check_no_collisionE"] - pub static mut MyClass_example_check_no_collision: - *const ::std::os::raw::c_int; -} -#[test] -fn bindgen_test_layout_MyClass() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(MyClass)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(MyClass)) - ); -} -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/tests/expectations/tests/class_static_const.rs b/tests/expectations/tests/class_static_const.rs deleted file mode 100644 index 812d78e1ab..0000000000 --- a/tests/expectations/tests/class_static_const.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct A { - pub _address: u8, -} -pub const A_a: ::std::os::raw::c_int = 0; -pub const A_b: i32 = 63; -pub const A_c: u32 = 255; -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} diff --git a/tests/expectations/tests/class_use_as.rs b/tests/expectations/tests/class_use_as.rs deleted file mode 100644 index d6a71ac358..0000000000 --- a/tests/expectations/tests/class_use_as.rs +++ /dev/null @@ -1,67 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct whatever { - pub replacement: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_whatever() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(whatever)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(whatever)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).replacement as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(whatever), - "::", - stringify!(replacement) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct container { - pub c: whatever, -} -#[test] -fn bindgen_test_layout_container() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(container)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(container)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(container), - "::", - stringify!(c) - ) - ); -} diff --git a/tests/expectations/tests/class_with_dtor.rs b/tests/expectations/tests/class_with_dtor.rs deleted file mode 100644 index 0cf2d8d236..0000000000 --- a/tests/expectations/tests/class_with_dtor.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct HandleWithDtor { - pub ptr: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for HandleWithDtor { - 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 type HandleValue = HandleWithDtor<::std::os::raw::c_int>; -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct WithoutDtor { - pub shouldBeWithDtor: HandleValue, -} -#[test] -fn bindgen_test_layout_WithoutDtor() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(WithoutDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(WithoutDtor)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).shouldBeWithDtor as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithoutDtor), - "::", - stringify!(shouldBeWithDtor) - ) - ); -} -impl Default for WithoutDtor { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_HandleWithDtor_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(HandleWithDtor<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(HandleWithDtor<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/class_with_inner_struct.rs b/tests/expectations/tests/class_with_inner_struct.rs deleted file mode 100644 index 35ed765914..0000000000 --- a/tests/expectations/tests/class_with_inner_struct.rs +++ /dev/null @@ -1,492 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(A_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(A_Segment), - "::", - stringify!(end) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union A__bindgen_ty_1 { - pub f: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).f as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A__bindgen_ty_1), - "::", - stringify!(f) - ) - ); -} -impl Default for A__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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union A__bindgen_ty_2 { - pub d: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A__bindgen_ty_2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A__bindgen_ty_2), - "::", - stringify!(d) - ) - ); -} -impl Default for A__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::
(), - 12usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(c)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).named_union as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(A), - "::", - stringify!(named_union) - ) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct B { - pub d: ::std::os::raw::c_uint, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(B_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(B_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(B_Segment), - "::", - stringify!(end) - ) - ); -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(B), "::", stringify!(d)) - ); -} -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum StepSyntax { - Keyword = 0, - FunctionalWithoutKeyword = 1, - FunctionalWithStartKeyword = 2, - FunctionalWithEndKeyword = 3, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct C { - pub d: ::std::os::raw::c_uint, - pub __bindgen_anon_1: C__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union C__bindgen_ty_1 { - pub mFunc: C__bindgen_ty_1__bindgen_ty_1, - pub __bindgen_anon_1: C__bindgen_ty_1__bindgen_ty_2, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mX1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mX1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mY1 - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mY1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mX2 - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mX2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mY2 - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mY2) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .mStepSyntax as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(mStepSyntax) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mSteps - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(mSteps) - ) - ); -} -impl Default for C__bindgen_ty_1__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_C__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFunc as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1), - "::", - stringify!(mFunc) - ) - ); -} -impl Default for C__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() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_Segment), - "::", - stringify!(end) - ) - ); -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 20usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(d)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/class_with_inner_struct_1_0.rs b/tests/expectations/tests/class_with_inner_struct_1_0.rs deleted file mode 100644 index 52cd590d67..0000000000 --- a/tests/expectations/tests/class_with_inner_struct_1_0.rs +++ /dev/null @@ -1,548 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(A_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(A_Segment), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).f as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A__bindgen_ty_2), - "::", - stringify!(d) - ) - ); -} -impl Clone for A__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(c)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).named_union as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(A), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(B_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(B_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(B_Segment), - "::", - stringify!(end) - ) - ); -} -impl Clone for B_Segment { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(B), "::", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mX1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mX1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mY1 - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mY1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mX2 - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(mX2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mY2 - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .mStepSyntax as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(mStepSyntax) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mSteps - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFunc as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C_Segment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_Segment)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).begin as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_Segment), - "::", - stringify!(begin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).end as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_Segment), - "::", - stringify!(end) - ) - ); -} -impl Clone for C_Segment { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 20usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(d)) - ); -} -impl Clone for C { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/class_with_typedef.rs b/tests/expectations/tests/class_with_typedef.rs deleted file mode 100644 index 31faa49ddb..0000000000 --- a/tests/expectations/tests/class_with_typedef.rs +++ /dev/null @@ -1,138 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type AnotherInt = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct C { - pub c: C_MyInt, - pub ptr: *mut C_MyInt, - pub arr: [C_MyInt; 10usize], - pub d: AnotherInt, - pub other_ptr: *mut AnotherInt, -} -pub type C_MyInt = ::std::os::raw::c_int; -pub type C_Lookup = *const ::std::os::raw::c_char; -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 72usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(c)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(ptr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).arr as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(arr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 56usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).other_ptr as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(other_ptr) - ) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1C6methodEi"] - pub fn C_method(this: *mut C, c: C_MyInt); -} -extern "C" { - #[link_name = "\u{1}_ZN1C9methodRefERi"] - pub fn C_methodRef(this: *mut C, c: *mut C_MyInt); -} -extern "C" { - #[link_name = "\u{1}_ZN1C16complexMethodRefERPKc"] - pub fn C_complexMethodRef(this: *mut C, c: *mut C_Lookup); -} -extern "C" { - #[link_name = "\u{1}_ZN1C13anotherMethodEi"] - pub fn C_anotherMethod(this: *mut C, c: AnotherInt); -} -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 unsafe fn method(&mut self, c: C_MyInt) { - C_method(self, c) - } - #[inline] - pub unsafe fn methodRef(&mut self, c: *mut C_MyInt) { - C_methodRef(self, c) - } - #[inline] - pub unsafe fn complexMethodRef(&mut self, c: *mut C_Lookup) { - C_complexMethodRef(self, c) - } - #[inline] - pub unsafe fn anotherMethod(&mut self, c: AnotherInt) { - C_anotherMethod(self, c) - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct D { - pub _base: C, - pub ptr: *mut C_MyInt, -} -#[test] -fn bindgen_test_layout_D() { - assert_eq!( - ::std::mem::size_of::(), - 80usize, - concat!("Size of: ", stringify!(D)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(D)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 72usize, - concat!("Offset of field: ", stringify!(D), "::", stringify!(ptr)) - ); -} -impl Default for D { - 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/tests/expectations/tests/comment-indent.rs b/tests/expectations/tests/comment-indent.rs deleted file mode 100644 index c381b7342b..0000000000 --- a/tests/expectations/tests/comment-indent.rs +++ /dev/null @@ -1,136 +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 { - #[allow(unused_imports)] - use self::super::root; - /// This is a multi-line doc comment. - /// - /// This class is really really interesting, look! - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Foo { - pub _address: u8, - } - /// This nested class is also a multi-line doc comment. - /// - /// This class is not so interesting, but worth a bit of docs too! - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Foo_Bar { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Foo_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo_Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo_Bar)) - ); - } - #[test] - fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); - } - pub mod test { - #[allow(unused_imports)] - use self::super::super::root; - /// I'm in a namespace, and thus I may be on a rust module, most of the time. - /// My documentation is pretty extensive, I guess. - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Baz { - /// This member is plain awesome, just amazing. - /// - /// It also has super-extensive docs, with even a nice ascii-art diagram. - /// - /// +------+ +-------+ - /// | foo | ----> | bar | - /// +------+ +-------+ - pub member: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Baz)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).member as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Baz), - "::", - stringify!(member) - ) - ); - } - /// I'm in an inline namespace, and as such I shouldn't get generated inside - /// a rust module, except when the relevant option is specified. Also, this - /// comment shouldn't be misaligned. - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct InInlineNS { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_InInlineNS() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(InInlineNS)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(InInlineNS)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bazz { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Bazz() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bazz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bazz)) - ); - } - } -} diff --git a/tests/expectations/tests/complex.rs b/tests/expectations/tests/complex.rs deleted file mode 100644 index 4dae071727..0000000000 --- a/tests/expectations/tests/complex.rs +++ /dev/null @@ -1,153 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] -#[repr(C)] -pub struct __BindgenComplex { - pub re: T, - pub im: T, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialEq)] -pub struct TestDouble { - pub mMember: __BindgenComplex, -} -#[test] -fn bindgen_test_layout_TestDouble() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(TestDouble)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(TestDouble)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mMember as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(TestDouble), - "::", - stringify!(mMember) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct TestDoublePtr { - pub mMember: *mut __BindgenComplex, -} -#[test] -fn bindgen_test_layout_TestDoublePtr() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(TestDoublePtr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(TestDoublePtr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mMember as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(TestDoublePtr), - "::", - stringify!(mMember) - ) - ); -} -impl Default for TestDoublePtr { - 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, Default, Copy, Clone, PartialEq)] -pub struct TestFloat { - pub mMember: __BindgenComplex, -} -#[test] -fn bindgen_test_layout_TestFloat() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(TestFloat)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(TestFloat)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mMember as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(TestFloat), - "::", - stringify!(mMember) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct TestFloatPtr { - pub mMember: *mut __BindgenComplex, -} -#[test] -fn bindgen_test_layout_TestFloatPtr() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(TestFloatPtr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(TestFloatPtr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mMember as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(TestFloatPtr), - "::", - stringify!(mMember) - ) - ); -} -impl Default for TestFloatPtr { - 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/tests/expectations/tests/complex_global.rs b/tests/expectations/tests/complex_global.rs deleted file mode 100644 index f21735da53..0000000000 --- a/tests/expectations/tests/complex_global.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] -#[repr(C)] -pub struct __BindgenComplex { - pub re: T, - pub im: T, -} -extern "C" { - pub static mut globalValueFloat: __BindgenComplex; -} -extern "C" { - pub static mut globalValueDouble: __BindgenComplex; -} -extern "C" { - pub static mut globalValueLongDouble: __BindgenComplex; -} diff --git a/tests/expectations/tests/const-const-mut-ptr.rs b/tests/expectations/tests/const-const-mut-ptr.rs deleted file mode 100644 index bc1e76277a..0000000000 --- a/tests/expectations/tests/const-const-mut-ptr.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub bar: *const *const *mut *const ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/const_array.rs b/tests/expectations/tests/const_array.rs deleted file mode 100644 index 191bac9c3f..0000000000 --- a/tests/expectations/tests/const_array.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub static foo: [::std::os::raw::c_int; 1usize]; -} -extern "C" { - pub static mut bar: [::std::os::raw::c_int; 1usize]; -} diff --git a/tests/expectations/tests/const_array_fn_arg.rs b/tests/expectations/tests/const_array_fn_arg.rs deleted file mode 100644 index 3286dce1be..0000000000 --- a/tests/expectations/tests/const_array_fn_arg.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn f(a: *const ::std::os::raw::c_int); -} diff --git a/tests/expectations/tests/const_enum_unnamed.rs b/tests/expectations/tests/const_enum_unnamed.rs deleted file mode 100644 index da0ec2b82d..0000000000 --- a/tests/expectations/tests/const_enum_unnamed.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const FOO_BAR: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAR; -pub const FOO_BAZ: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAZ; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - FOO_BAR = 0, - FOO_BAZ = 1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -pub const Foo_FOO_BAR: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::FOO_BAR; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo__bindgen_ty_1 { - FOO_BAR = 10, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/const_multidim_array_fn_arg.rs b/tests/expectations/tests/const_multidim_array_fn_arg.rs deleted file mode 100644 index 11ae184d85..0000000000 --- a/tests/expectations/tests/const_multidim_array_fn_arg.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn f(a: *const [::std::os::raw::c_int; 1usize]); -} diff --git a/tests/expectations/tests/const_ptr.rs b/tests/expectations/tests/const_ptr.rs deleted file mode 100644 index 0087aa99ee..0000000000 --- a/tests/expectations/tests/const_ptr.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(bar: *const ::std::os::raw::c_void); -} diff --git a/tests/expectations/tests/const_resolved_ty.rs b/tests/expectations/tests/const_resolved_ty.rs deleted file mode 100644 index 66939ef932..0000000000 --- a/tests/expectations/tests/const_resolved_ty.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(foo: *const u8); -} diff --git a/tests/expectations/tests/constant-non-specialized-tp.rs b/tests/expectations/tests/constant-non-specialized-tp.rs deleted file mode 100644 index 6c1e3d382a..0000000000 --- a/tests/expectations/tests/constant-non-specialized-tp.rs +++ /dev/null @@ -1,22 +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 Test { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Outer { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Outer_Inner { - pub _address: u8, -} diff --git a/tests/expectations/tests/constified-enum-module-overflow.rs b/tests/expectations/tests/constified-enum-module-overflow.rs deleted file mode 100644 index 4a799ef8e5..0000000000 --- a/tests/expectations/tests/constified-enum-module-overflow.rs +++ /dev/null @@ -1,54 +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 B { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct C { - pub _address: u8, -} -pub type C_U = B; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub u: u8, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(u)) - ); -} -#[test] -fn __bindgen_test_layout_C_open0_A_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(C)) - ); -} diff --git a/tests/expectations/tests/constify-all-enums.rs b/tests/expectations/tests/constify-all-enums.rs deleted file mode 100644 index 78bb99faf5..0000000000 --- a/tests/expectations/tests/constify-all-enums.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo_THIS: foo = 0; -pub const foo_SHOULD_BE: foo = 1; -pub const foo_A_CONSTANT: foo = 2; -pub type foo = ::std::os::raw::c_uint; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct bar { - pub this_should_work: foo, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).this_should_work as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(this_should_work) - ) - ); -} -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/tests/expectations/tests/constify-enum.rs b/tests/expectations/tests/constify-enum.rs deleted file mode 100644 index 091743e945..0000000000 --- a/tests/expectations/tests/constify-enum.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue: - nsCSSPropertyID = - nsCSSPropertyID::eCSSProperty_COUNT_unexistingVariantValue; -impl nsCSSPropertyID { - pub const eCSSProperty_COUNT: nsCSSPropertyID = - nsCSSPropertyID::eCSSPropertyAlias_aa; -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum nsCSSPropertyID { - eCSSProperty_a = 0, - eCSSProperty_b = 1, - eCSSPropertyAlias_aa = 2, - eCSSPropertyAlias_bb = 3, - ///<
- eCSSProperty_COUNT_unexistingVariantValue = 4, -} diff --git a/tests/expectations/tests/constify-module-enums-basic.rs b/tests/expectations/tests/constify-module-enums-basic.rs deleted file mode 100644 index 59e9ba12ba..0000000000 --- a/tests/expectations/tests/constify-module-enums-basic.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod foo { - pub type Type = ::std::os::raw::c_uint; - pub const THIS: Type = 0; - pub const SHOULD_BE: Type = 1; - pub const A_CONSTANT: Type = 2; -} -pub use self::foo::Type as foo_alias1; -pub use self::foo_alias1 as foo_alias2; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct bar { - pub this_should_work: foo::Type, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).this_should_work as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(this_should_work) - ) - ); -} -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() - } - } -} -extern "C" { - pub fn func1( - arg1: foo::Type, - arg2: *mut foo::Type, - arg3: *mut *mut foo::Type, - ) -> *mut foo::Type; -} -extern "C" { - pub fn func2( - arg1: foo_alias1, - arg2: *mut foo_alias1, - arg3: *mut *mut foo_alias1, - ) -> *mut foo_alias1; -} diff --git a/tests/expectations/tests/constify-module-enums-namespace.rs b/tests/expectations/tests/constify-module-enums-namespace.rs deleted file mode 100644 index e434291a15..0000000000 --- a/tests/expectations/tests/constify-module-enums-namespace.rs +++ /dev/null @@ -1,70 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod ns1 { - #[allow(unused_imports)] - use self::super::super::root; - pub mod ns2 { - #[allow(unused_imports)] - use self::super::super::super::root; - pub mod foo { - pub type Type = ::std::os::raw::c_uint; - pub const THIS: Type = 0; - pub const SHOULD_BE: Type = 1; - pub const A_CONSTANT: Type = 2; - } - } - pub mod ns3 { - #[allow(unused_imports)] - use self::super::super::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct bar { - pub this_should_work: root::ns1::ns2::foo::Type, - } - #[test] - fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).this_should_work - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(this_should_work) - ) - ); - } - 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/tests/expectations/tests/constify-module-enums-shadow-name.rs b/tests/expectations/tests/constify-module-enums-shadow-name.rs deleted file mode 100644 index 60401dc093..0000000000 --- a/tests/expectations/tests/constify-module-enums-shadow-name.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod foo { - pub type Type = ::std::os::raw::c_uint; - pub const Type: Type = 0; - pub const Type_: Type = 1; - pub const Type1: Type = 2; - pub const Type__: Type = 3; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct bar { - pub member: foo::Type, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member) - ) - ); -} -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/tests/expectations/tests/constify-module-enums-simple-alias.rs b/tests/expectations/tests/constify-module-enums-simple-alias.rs deleted file mode 100644 index 317697dd3b..0000000000 --- a/tests/expectations/tests/constify-module-enums-simple-alias.rs +++ /dev/null @@ -1,118 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod Foo { - pub type Type = ::std::os::raw::c_int; - pub const Variant1: Type = 0; - pub const Variant2: Type = 1; - pub const Variant3: Type = 2; -} -pub use self::Foo::Type as Foo_alias1; -pub use self::Foo_alias1 as Foo_alias2; -pub use self::Foo_alias2 as Foo_alias3; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Bar { - pub baz1: Foo::Type, - pub baz2: Foo_alias1, - pub baz3: Foo_alias2, - pub baz4: Foo_alias3, - pub baz_ptr1: *mut Foo::Type, - pub baz_ptr2: *mut Foo_alias1, - pub baz_ptr3: *mut Foo_alias2, - pub baz_ptr4: *mut Foo_alias3, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz1 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz1)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz2 as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz2)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz3 as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz3)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz4 as *const _ as usize }, - 12usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz4)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz_ptr1 as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz_ptr1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz_ptr2 as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz_ptr2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz_ptr3 as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz_ptr3) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz_ptr4 as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz_ptr4) - ) - ); -} -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/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs b/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs deleted file mode 100644 index b6644797d7..0000000000 --- a/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod one_Foo { - pub type Type = ::std::os::raw::c_int; - pub const Variant1: Type = 0; - pub const Variant2: Type = 1; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Bar { - pub baz1: one_Foo::Type, - pub baz2: *mut one_Foo::Type, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz1 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz1)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz2 as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz2)) - ); -} -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/tests/expectations/tests/constify-module-enums-types.rs b/tests/expectations/tests/constify-module-enums-types.rs deleted file mode 100644 index ec7e6c0eee..0000000000 --- a/tests/expectations/tests/constify-module-enums-types.rs +++ /dev/null @@ -1,290 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod foo { - pub type Type = ::std::os::raw::c_uint; - pub const THIS: Type = 0; - pub const SHOULD_BE: Type = 1; - pub const A_CONSTANT: Type = 2; - pub const ALSO_THIS: Type = 42; - pub const AND_ALSO_THIS: Type = 42; -} -pub mod anon_enum { - 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 { - pub type Type = ::std::os::raw::c_uint; - pub const THIS: Type = 0; - pub const SHOULD_BE: Type = 1; - pub const A_CONSTANT: Type = 2; - pub const ALSO_THIS: Type = 42; -} -pub mod ns2_Foo { - pub type Type = ::std::os::raw::c_int; - pub const Variant1: Type = 0; - pub const Variant2: Type = 1; -} -pub use self::anon_enum::Type as anon_enum_alias1; -pub use self::anon_enum_alias1 as anon_enum_alias2; -pub use self::anon_enum_alias2 as anon_enum_alias3; -pub use self::foo::Type as foo_alias1; -pub use self::foo_alias1 as foo_alias2; -pub use self::foo_alias2 as foo_alias3; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct bar { - pub member1: foo::Type, - pub member2: foo_alias1, - pub member3: foo_alias2, - pub member4: foo_alias3, - pub member5: ns1_foo::Type, - pub member6: *mut ns2_Foo::Type, - pub member7: anon_enum::Type, - pub member8: anon_enum_alias1, - pub member9: anon_enum_alias2, - pub member10: anon_enum_alias3, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member1 as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member1) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member2 as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member3 as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member3) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member4 as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member4) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member5 as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member5) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member6 as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member6) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member7 as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member7) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member8 as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member8) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member9 as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member9) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).member10 as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(member10) - ) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Baz { - pub member1: ns2_Foo::Type, -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member1 as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Baz), - "::", - stringify!(member1) - ) - ); -} -impl Default for Baz { - 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 mod one_Foo { - pub type Type = ::std::os::raw::c_int; - pub const Variant1: Type = 0; - pub const Variant2: Type = 1; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Bar { - pub baz: *mut one_Foo::Type, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz)) - ); -} -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() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z5func13fooPS_PS0_"] - pub fn func1( - arg1: foo::Type, - arg2: *mut foo::Type, - arg3: *mut *mut foo::Type, - ) -> *mut foo::Type; -} -extern "C" { - #[link_name = "\u{1}_Z5func23fooPS_PS0_"] - pub fn func2( - arg1: foo_alias1, - arg2: *mut foo_alias1, - arg3: *mut *mut foo_alias1, - ) -> *mut foo_alias1; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Thing { - pub thing: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Thing { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z5func35ThingI3fooE"] - pub fn func3(arg1: Thing) -> foo::Type; -} -extern "C" { - #[link_name = "\u{1}_Z5func45ThingIS_I3fooEE"] - pub fn func4(arg1: Thing>) -> foo::Type; -} diff --git a/tests/expectations/tests/constructor-tp.rs b/tests/expectations/tests/constructor-tp.rs deleted file mode 100644 index 4b339dc3c4..0000000000 --- a/tests/expectations/tests/constructor-tp.rs +++ /dev/null @@ -1,42 +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, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3BarC1Ev"] - pub fn Bar_Bar(this: *mut Bar); -} -impl Bar { - #[inline] - pub unsafe fn new() -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Bar_Bar(__bindgen_tmp.as_mut_ptr()); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/constructors.rs b/tests/expectations/tests/constructors.rs deleted file mode 100644 index 2f13effbef..0000000000 --- a/tests/expectations/tests/constructors.rs +++ /dev/null @@ -1,80 +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 TestOverload { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_TestOverload() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(TestOverload)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(TestOverload)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN12TestOverloadC1Ei"] - pub fn TestOverload_TestOverload( - this: *mut TestOverload, - arg1: ::std::os::raw::c_int, - ); -} -extern "C" { - #[link_name = "\u{1}_ZN12TestOverloadC1Ed"] - pub fn TestOverload_TestOverload1(this: *mut TestOverload, arg1: f64); -} -impl TestOverload { - #[inline] - pub unsafe fn new(arg1: ::std::os::raw::c_int) -> Self { - 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::MaybeUninit::uninit(); - TestOverload_TestOverload1(__bindgen_tmp.as_mut_ptr(), arg1); - __bindgen_tmp.assume_init() - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct TestPublicNoArgs { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_TestPublicNoArgs() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(TestPublicNoArgs)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(TestPublicNoArgs)) - ); -} -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::MaybeUninit::uninit(); - TestPublicNoArgs_TestPublicNoArgs(__bindgen_tmp.as_mut_ptr()); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/constructors_1_33.rs b/tests/expectations/tests/constructors_1_33.rs deleted file mode 100644 index b5d333325b..0000000000 --- a/tests/expectations/tests/constructors_1_33.rs +++ /dev/null @@ -1,82 +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 TestOverload { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_TestOverload() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(TestOverload)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(TestOverload)) - ); -} -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( - this: *mut TestOverload, - arg1: ::std::os::raw::c_int, - ); -} -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); -} -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 - } - #[inline] - pub unsafe fn new1(arg1: f64) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - TestOverload_TestOverload1(&mut __bindgen_tmp, arg1); - __bindgen_tmp - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct TestPublicNoArgs { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_TestPublicNoArgs() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(TestPublicNoArgs)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(TestPublicNoArgs)) - ); -} -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 - } -} diff --git a/tests/expectations/tests/contains-vs-inherits-zero-sized.rs b/tests/expectations/tests/contains-vs-inherits-zero-sized.rs deleted file mode 100644 index 2882fa845d..0000000000 --- a/tests/expectations/tests/contains-vs-inherits-zero-sized.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This should get an `_address` byte. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Empty { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Empty() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Empty)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Empty)) - ); -} -/// This should not get an `_address` byte, so `sizeof(Inherits)` should be -/// `1`. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Inherits { - pub b: bool, -} -#[test] -fn bindgen_test_layout_Inherits() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Inherits)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Inherits)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Inherits), - "::", - stringify!(b) - ) - ); -} -/// This should not get an `_address` byte, but contains `Empty` which *does* get -/// one, so `sizeof(Contains)` should be `1 + 1`. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Contains { - pub empty: Empty, - pub b: bool, -} -#[test] -fn bindgen_test_layout_Contains() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(Contains)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Contains)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).empty as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Contains), - "::", - stringify!(empty) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 1usize, - concat!( - "Offset of field: ", - stringify!(Contains), - "::", - stringify!(b) - ) - ); -} diff --git a/tests/expectations/tests/convert-cpp-comment-to-rust.rs b/tests/expectations/tests/convert-cpp-comment-to-rust.rs deleted file mode 100644 index 86279caf47..0000000000 --- a/tests/expectations/tests/convert-cpp-comment-to-rust.rs +++ /dev/null @@ -1,77 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type mbedtls_mpi_uint = ::std::os::raw::c_uint; -/// \brief MPI structure -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct mbedtls_mpi { - ///< integer sign - pub s: ::std::os::raw::c_int, - ///< total # of limbs - pub n: ::std::os::raw::c_ulong, - ///< pointer to limbs - pub p: *mut mbedtls_mpi_uint, -} -#[test] -fn bindgen_test_layout_mbedtls_mpi() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(mbedtls_mpi)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(mbedtls_mpi)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).s as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(mbedtls_mpi), - "::", - stringify!(s) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).n as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(mbedtls_mpi), - "::", - stringify!(n) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).p as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(mbedtls_mpi), - "::", - stringify!(p) - ) - ); -} -impl Default for mbedtls_mpi { - 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/tests/expectations/tests/convert-floats.rs b/tests/expectations/tests/convert-floats.rs deleted file mode 100644 index 6623159211..0000000000 --- a/tests/expectations/tests/convert-floats.rs +++ /dev/null @@ -1,94 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] -#[repr(C)] -pub struct __BindgenComplex { - pub re: T, - pub im: T, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub bar: ::std::os::raw::c_float, - pub baz: ::std::os::raw::c_float, - pub bazz: ::std::os::raw::c_double, - pub bazzz: *mut u128, - pub complexFloat: __BindgenComplex<::std::os::raw::c_float>, - pub complexDouble: __BindgenComplex<::std::os::raw::c_double>, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bazz as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bazz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bazzz as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(bazzz) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).complexFloat as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(complexFloat) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).complexDouble as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(complexDouble) - ) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/cpp-empty-layout.rs b/tests/expectations/tests/cpp-empty-layout.rs deleted file mode 100644 index f5ba025a25..0000000000 --- a/tests/expectations/tests/cpp-empty-layout.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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/crtp.rs b/tests/expectations/tests/crtp.rs deleted file mode 100644 index 2372e21153..0000000000 --- a/tests/expectations/tests/crtp.rs +++ /dev/null @@ -1,86 +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 Base { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Derived { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Derived() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Derived)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Derived)) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct BaseWithDestructor { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct DerivedFromBaseWithDestructor { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_DerivedFromBaseWithDestructor() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(DerivedFromBaseWithDestructor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(DerivedFromBaseWithDestructor)) - ); -} -#[test] -fn __bindgen_test_layout_Base_open0_Derived_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(Base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(Base)) - ); -} -#[test] -fn __bindgen_test_layout_BaseWithDestructor_open0_DerivedFromBaseWithDestructor_close0_instantiation( -) { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!( - "Size of template specialization: ", - stringify!(BaseWithDestructor) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(BaseWithDestructor) - ) - ); -} diff --git a/tests/expectations/tests/ctypes-prefix-path.rs b/tests/expectations/tests/ctypes-prefix-path.rs deleted file mode 100644 index 12cedac955..0000000000 --- a/tests/expectations/tests/ctypes-prefix-path.rs +++ /dev/null @@ -1,58 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![no_std] -mod libc { - pub mod foo { - pub type c_int = i32; - pub enum c_void {} - } -} - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub a: libc::foo::c_int, - pub b: libc::foo::c_int, - pub bar: *mut libc::foo::c_void, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).b as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).bar as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Default for foo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} diff --git a/tests/expectations/tests/dash_language.rs b/tests/expectations/tests/dash_language.rs deleted file mode 100644 index eb2bbc7689..0000000000 --- a/tests/expectations/tests/dash_language.rs +++ /dev/null @@ -1,12 +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 bar: ::std::os::raw::c_int, -} diff --git a/tests/expectations/tests/decl_extern_int_twice.rs b/tests/expectations/tests/decl_extern_int_twice.rs deleted file mode 100644 index d812b03238..0000000000 --- a/tests/expectations/tests/decl_extern_int_twice.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub static mut foo: ::std::os::raw::c_int; -} diff --git a/tests/expectations/tests/decl_ptr_to_array.rs b/tests/expectations/tests/decl_ptr_to_array.rs deleted file mode 100644 index b520f1e033..0000000000 --- a/tests/expectations/tests/decl_ptr_to_array.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub static mut foo: *mut [::std::os::raw::c_int; 1usize]; -} diff --git a/tests/expectations/tests/default-enum-style-constified-module.rs b/tests/expectations/tests/default-enum-style-constified-module.rs deleted file mode 100644 index 5e225e3db6..0000000000 --- a/tests/expectations/tests/default-enum-style-constified-module.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod Foo { - 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" { - pub fn func(x: Foo::Type); -} diff --git a/tests/expectations/tests/default-template-parameter.rs b/tests/expectations/tests/default-template-parameter.rs deleted file mode 100644 index 2cbe463cd9..0000000000 --- a/tests/expectations/tests/default-template-parameter.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - pub t: T, - pub u: U, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -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() - } - } -} -#[test] -fn __bindgen_test_layout_Foo_open0_bool__int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify ! (Foo < bool , :: std :: os :: raw :: c_int >) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify ! (Foo < bool , :: std :: os :: raw :: c_int >) - ) - ); -} -extern "C" { - #[link_name = "\u{1}_ZL3bar"] - pub static mut bar: Foo; -} diff --git a/tests/expectations/tests/deleted-function.rs b/tests/expectations/tests/deleted-function.rs deleted file mode 100644 index 96967bb461..0000000000 --- a/tests/expectations/tests/deleted-function.rs +++ /dev/null @@ -1,91 +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 A { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::
(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1A17inline_definitionEv"] - pub fn A_inline_definition(this: *mut A); -} -extern "C" { - #[link_name = "\u{1}_ZN1A22out_of_line_definitionEv"] - pub fn A_out_of_line_definition(this: *mut A); -} -impl A { - #[inline] - pub unsafe fn inline_definition(&mut self) { - A_inline_definition(self) - } - #[inline] - pub unsafe fn out_of_line_definition(&mut self) { - A_out_of_line_definition(self) - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct B { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(B)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct C { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(C)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1CC1ERS_"] - pub fn C_C(this: *mut C, arg1: *mut C); -} -impl C { - #[inline] - pub unsafe fn new(arg1: *mut C) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - C_C(__bindgen_tmp.as_mut_ptr(), arg1); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/derive-bitfield-method-same-name.rs b/tests/expectations/tests/derive-bitfield-method-same-name.rs deleted file mode 100644 index 1dc1d6e350..0000000000 --- a/tests/expectations/tests/derive-bitfield-method-same-name.rs +++ /dev/null @@ -1,212 +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 const 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); - } - } -} -/// 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)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 136usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).large as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(large) - ) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo4typeEv"] - pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; -} -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" { - #[link_name = "\u{1}_ZN3Foo8set_typeEc"] - pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); -} -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 ::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 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) - } - } - #[inline] - pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 3u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - type__bindgen_bitfield: ::std::os::raw::c_char, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let type__bindgen_bitfield: u8 = - unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; - type__bindgen_bitfield as u64 - }); - __bindgen_bitfield_unit - } - #[inline] - pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { - Foo_type(self) - } - #[inline] - pub unsafe fn set_type_(&mut self, c: ::std::os::raw::c_char) { - Foo_set_type_(self, c) - } - #[inline] - pub unsafe fn set_type(&mut self, c: ::std::os::raw::c_char) { - Foo_set_type(self, c) - } -} diff --git a/tests/expectations/tests/derive-clone.rs b/tests/expectations/tests/derive-clone.rs deleted file mode 100644 index e589a29ea3..0000000000 --- a/tests/expectations/tests/derive-clone.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This struct should derive `Clone`. -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ShouldDeriveClone { - pub large: [::std::os::raw::c_int; 33usize], -} -#[test] -fn bindgen_test_layout_ShouldDeriveClone() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(ShouldDeriveClone)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ShouldDeriveClone)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldDeriveClone), - "::", - stringify!(large) - ) - ); -} -impl Default for ShouldDeriveClone { - 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/tests/expectations/tests/derive-clone_1_0.rs b/tests/expectations/tests/derive-clone_1_0.rs deleted file mode 100644 index a437d5c314..0000000000 --- a/tests/expectations/tests/derive-clone_1_0.rs +++ /dev/null @@ -1,54 +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() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(ShouldImplClone)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ShouldImplClone)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldImplClone), - "::", - stringify!(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/tests/expectations/tests/derive-custom.rs b/tests/expectations/tests/derive-custom.rs deleted file mode 100644 index 1cae9af0ae..0000000000 --- a/tests/expectations/tests/derive-custom.rs +++ /dev/null @@ -1,95 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[derive(Default, Debug)] -pub struct my_type { - pub a: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_my_type() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(my_type)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(my_type)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(my_type), - "::", - stringify!(a) - ) - ); -} -///
-///
-#[repr(C)] -#[derive(Default, Debug, Clone)] -pub struct my_type2 { - pub a: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_my_type2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(my_type2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(my_type2)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(my_type2), - "::", - stringify!(a) - ) - ); -} -///
-#[repr(C)] -#[derive(Default, Debug, Clone)] -pub struct my_type3 { - pub a: ::std::os::raw::c_ulong, -} -#[test] -fn bindgen_test_layout_my_type3() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(my_type3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(my_type3)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(my_type3), - "::", - stringify!(a) - ) - ); -} diff --git a/tests/expectations/tests/derive-debug-bitfield-core.rs b/tests/expectations/tests/derive-debug-bitfield-core.rs deleted file mode 100644 index 33f0f2ffbc..0000000000 --- a/tests/expectations/tests/derive-debug-bitfield-core.rs +++ /dev/null @@ -1,191 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate core; - -#[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] - 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)] -#[derive(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() { - assert_eq!( - ::core::mem::size_of::(), - 204usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).large_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(large_array) - ) - ); -} -impl Default for C { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -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 { - unsafe { - ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) - } - } - #[inline] - pub fn set_a(&mut self, val: bool) { - unsafe { - let val: u8 = ::core::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn b(&self) -> bool { - unsafe { - ::core::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) - } - } - #[inline] - pub fn set_b(&mut self, val: bool) { - unsafe { - let val: u8 = ::core::mem::transmute(val); - self._bitfield_1.set(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 { ::core::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 7u8, { - let b: u8 = unsafe { ::core::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/derive-debug-bitfield.rs b/tests/expectations/tests/derive-debug-bitfield.rs deleted file mode 100644 index 00976b59df..0000000000 --- a/tests/expectations/tests/derive-debug-bitfield.rs +++ /dev/null @@ -1,198 +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 const 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)] -#[derive(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() { - assert_eq!( - ::std::mem::size_of::(), - 204usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(large_array) - ) - ); -} -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 ::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 { - 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 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 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/tests/expectations/tests/derive-debug-function-pointer.rs b/tests/expectations/tests/derive-debug-function-pointer.rs deleted file mode 100644 index c031897b6a..0000000000 --- a/tests/expectations/tests/derive-debug-function-pointer.rs +++ /dev/null @@ -1,79 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Nice { - pub pointer: Nice_Function, - pub large_array: [::std::os::raw::c_int; 34usize], -} -pub type Nice_Function = - ::std::option::Option; -#[test] -fn bindgen_test_layout_Nice() { - assert_eq!( - ::std::mem::size_of::(), - 144usize, - concat!("Size of: ", stringify!(Nice)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Nice)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pointer as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Nice), - "::", - stringify!(pointer) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large_array as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(Nice), - "::", - stringify!(large_array) - ) - ); -} -impl Default for Nice { - 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 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/tests/expectations/tests/derive-debug-generic.rs b/tests/expectations/tests/derive-debug-generic.rs deleted file mode 100644 index 49d4e9b89e..0000000000 --- a/tests/expectations/tests/derive-debug-generic.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Generic { - pub t: [T; 40usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Generic { - 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 Generic { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Generic {{ t: Array with length 40 }}") - } -} diff --git a/tests/expectations/tests/derive-debug-mangle-name.rs b/tests/expectations/tests/derive-debug-mangle-name.rs deleted file mode 100644 index ed5416486c..0000000000 --- a/tests/expectations/tests/derive-debug-mangle-name.rs +++ /dev/null @@ -1,129 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct perf_event_attr { - pub type_: ::std::os::raw::c_uint, - pub a: f32, - pub __bindgen_anon_1: perf_event_attr__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union perf_event_attr__bindgen_ty_1 { - pub b: ::std::os::raw::c_int, - pub c: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_perf_event_attr__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(perf_event_attr__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(perf_event_attr__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(perf_event_attr__bindgen_ty_1), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(perf_event_attr__bindgen_ty_1), - "::", - stringify!(c) - ) - ); -} -impl Default for perf_event_attr__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 ::std::fmt::Debug for perf_event_attr__bindgen_ty_1 { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "perf_event_attr__bindgen_ty_1 {{ union }}") - } -} -#[test] -fn bindgen_test_layout_perf_event_attr() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(perf_event_attr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(perf_event_attr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).type_ as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(perf_event_attr), - "::", - stringify!(type_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(perf_event_attr), - "::", - stringify!(a) - ) - ); -} -impl Default for perf_event_attr { - 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 perf_event_attr { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!( - f, - "perf_event_attr {{ type: {:?}, a: {:?}, __bindgen_anon_1: {:?} }}", - self.type_, self.a, self.__bindgen_anon_1 - ) - } -} diff --git a/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs b/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs deleted file mode 100644 index ceb70ffe4e..0000000000 --- a/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Instance { - pub val: [u32; 50usize], -} -#[test] -fn bindgen_test_layout_Instance() { - assert_eq!( - ::std::mem::size_of::(), - 200usize, - concat!("Size of: ", stringify!(Instance)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Instance)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).val as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Instance), - "::", - stringify!(val) - ) - ); -} -impl Default for Instance { - 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 Instance { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Instance {{ val: opaque }}") - } -} diff --git a/tests/expectations/tests/derive-debug-opaque.rs b/tests/expectations/tests/derive-debug-opaque.rs deleted file mode 100644 index 411c7a7036..0000000000 --- a/tests/expectations/tests/derive-debug-opaque.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[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, - concat!("Size of: ", stringify!(Opaque)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Opaque)) - ); -} -impl Default for Opaque { - 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 Opaque { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Opaque {{ opaque }}") - } -} -#[repr(C)] -pub struct OpaqueUser { - pub opaque: Opaque, -} -#[test] -fn bindgen_test_layout_OpaqueUser() { - assert_eq!( - ::std::mem::size_of::(), - 164usize, - concat!("Size of: ", stringify!(OpaqueUser)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(OpaqueUser)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).opaque as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(OpaqueUser), - "::", - stringify!(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) - } -} diff --git a/tests/expectations/tests/derive-default-and-blocklist.rs b/tests/expectations/tests/derive-default-and-blocklist.rs deleted file mode 100644 index 5d53ede28c..0000000000 --- a/tests/expectations/tests/derive-default-and-blocklist.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub struct BlocklistMe(u8); - -/// Because this type contains a blocklisted type, it should not derive -/// Default. Instead, we should emit a `mem::zeroed` implementation. -#[repr(C)] -pub struct ShouldNotDeriveDefault { - pub a: BlocklistMe, -} -#[test] -fn bindgen_test_layout_ShouldNotDeriveDefault() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ShouldNotDeriveDefault)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ShouldNotDeriveDefault)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotDeriveDefault), - "::", - stringify!(a) - ) - ); -} -impl Default for ShouldNotDeriveDefault { - 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/tests/expectations/tests/derive-fn-ptr.rs b/tests/expectations/tests/derive-fn-ptr.rs deleted file mode 100644 index 7c9f426115..0000000000 --- a/tests/expectations/tests/derive-fn-ptr.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type my_fun_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: ::std::os::raw::c_int, - arg2: ::std::os::raw::c_int, - arg3: ::std::os::raw::c_int, - arg4: ::std::os::raw::c_int, - arg5: ::std::os::raw::c_int, - arg6: ::std::os::raw::c_int, - arg7: ::std::os::raw::c_int, - arg8: ::std::os::raw::c_int, - arg9: ::std::os::raw::c_int, - arg10: ::std::os::raw::c_int, - arg11: ::std::os::raw::c_int, - arg12: ::std::os::raw::c_int, - arg13: ::std::os::raw::c_int, - arg14: ::std::os::raw::c_int, - arg15: ::std::os::raw::c_int, - arg16: ::std::os::raw::c_int, - ), ->; -#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct Foo { - pub callback: my_fun_t, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).callback as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(callback) - ) - ); -} -pub type my_fun2_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: ::std::os::raw::c_int, - arg2: ::std::os::raw::c_int, - arg3: ::std::os::raw::c_int, - arg4: ::std::os::raw::c_int, - arg5: ::std::os::raw::c_int, - arg6: ::std::os::raw::c_int, - arg7: ::std::os::raw::c_int, - arg8: ::std::os::raw::c_int, - arg9: ::std::os::raw::c_int, - arg10: ::std::os::raw::c_int, - arg11: ::std::os::raw::c_int, - arg12: ::std::os::raw::c_int, - ), ->; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Bar { - pub callback: my_fun2_t, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).callback as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(callback) - ) - ); -} diff --git a/tests/expectations/tests/derive-hash-and-blocklist.rs b/tests/expectations/tests/derive-hash-and-blocklist.rs deleted file mode 100644 index 8e1190ea72..0000000000 --- a/tests/expectations/tests/derive-hash-and-blocklist.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub struct BlocklistMe(u8); - -/// Because this type contains a blocklisted type, it should not derive Hash. -#[repr(C)] -pub struct ShouldNotDeriveHash { - pub a: BlocklistMe, -} -#[test] -fn bindgen_test_layout_ShouldNotDeriveHash() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ShouldNotDeriveHash)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ShouldNotDeriveHash)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotDeriveHash), - "::", - stringify!(a) - ) - ); -} -impl Default for ShouldNotDeriveHash { - 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/tests/expectations/tests/derive-hash-blocklisting.rs b/tests/expectations/tests/derive-hash-blocklisting.rs deleted file mode 100644 index 7cd29c21d2..0000000000 --- a/tests/expectations/tests/derive-hash-blocklisting.rs +++ /dev/null @@ -1,93 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] -pub struct Blocklisted { - t: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} - -/// This would derive(Hash, Eq, PartialEq) if it didn't contain a blocklisted type, -/// causing us to conservatively avoid deriving hash/Eq/PartialEq for it. -#[repr(C)] -pub struct AllowlistedOne { - pub a: Blocklisted<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_AllowlistedOne() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AllowlistedOne)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(AllowlistedOne)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistedOne), - "::", - stringify!(a) - ) - ); -} -impl Default for AllowlistedOne { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// This can't derive(Hash/Eq) even if it didn't contain a blocklisted type. -#[repr(C)] -pub struct AllowlistedTwo { - pub b: Blocklisted, -} -#[test] -fn bindgen_test_layout_AllowlistedTwo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AllowlistedTwo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(AllowlistedTwo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AllowlistedTwo), - "::", - stringify!(b) - ) - ); -} -impl Default for AllowlistedTwo { - 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/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs b/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs deleted file mode 100644 index 92846f3c96..0000000000 --- a/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] -pub struct foo__bindgen_ty_1 { - pub a: f32, - pub b: f32, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/derive-hash-struct-with-float-array.rs b/tests/expectations/tests/derive-hash-struct-with-float-array.rs deleted file mode 100644 index e2e1bcef22..0000000000 --- a/tests/expectations/tests/derive-hash-struct-with-float-array.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)] -pub struct foo { - pub bar: [f32; 3usize], -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs b/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs deleted file mode 100644 index 851080749d..0000000000 --- a/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs +++ /dev/null @@ -1,113 +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 const 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)] -#[derive(Debug, Default)] -pub struct test { - pub a: ::std::os::raw::c_int, - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_test() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(test), "::", stringify!(a)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).zero_length_array as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(test), - "::", - stringify!(zero_length_array) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct test2 { - pub a: ::std::os::raw::c_int, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_test2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test2)) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct test3 { - 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_test3() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test3)) - ); -} diff --git a/tests/expectations/tests/derive-hash-struct-with-pointer.rs b/tests/expectations/tests/derive-hash-struct-with-pointer.rs deleted file mode 100644 index e98bbf0f32..0000000000 --- a/tests/expectations/tests/derive-hash-struct-with-pointer.rs +++ /dev/null @@ -1,165 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct ConstPtrMutObj { - pub bar: *mut ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ConstPtrMutObj() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ConstPtrMutObj)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ConstPtrMutObj)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ConstPtrMutObj), - "::", - stringify!(bar) - ) - ); -} -impl Default for ConstPtrMutObj { - 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, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct MutPtrMutObj { - pub bar: *mut ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_MutPtrMutObj() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(MutPtrMutObj)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(MutPtrMutObj)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(MutPtrMutObj), - "::", - stringify!(bar) - ) - ); -} -impl Default for MutPtrMutObj { - 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, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct MutPtrConstObj { - pub bar: *const ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_MutPtrConstObj() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(MutPtrConstObj)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(MutPtrConstObj)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(MutPtrConstObj), - "::", - stringify!(bar) - ) - ); -} -impl Default for MutPtrConstObj { - 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, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct ConstPtrConstObj { - pub bar: *const ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ConstPtrConstObj() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ConstPtrConstObj)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ConstPtrConstObj)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bar as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ConstPtrConstObj), - "::", - stringify!(bar) - ) - ); -} -impl Default for ConstPtrConstObj { - 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/tests/expectations/tests/derive-hash-template-inst-float.rs b/tests/expectations/tests/derive-hash-template-inst-float.rs deleted file mode 100644 index f861815234..0000000000 --- a/tests/expectations/tests/derive-hash-template-inst-float.rs +++ /dev/null @@ -1,129 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct foo { - pub data: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -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() - } - } -} -/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct IntStr { - pub a: foo<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_IntStr() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(IntStr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(IntStr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(IntStr), "::", stringify!(a)) - ); -} -impl Default for IntStr { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd -#[repr(C)] -#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] -pub struct FloatStr { - pub a: foo, -} -#[test] -fn bindgen_test_layout_FloatStr() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(FloatStr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(FloatStr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(FloatStr), - "::", - stringify!(a) - ) - ); -} -impl Default for FloatStr { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_foo_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(foo<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(foo<::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_foo_open0_float_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!("Size of template specialization: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(foo) - ) - ); -} diff --git a/tests/expectations/tests/derive-partialeq-and-blocklist.rs b/tests/expectations/tests/derive-partialeq-and-blocklist.rs deleted file mode 100644 index d9dfb44618..0000000000 --- a/tests/expectations/tests/derive-partialeq-and-blocklist.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub struct BlocklistMe(u8); - -/// Because this type contains a blocklisted type, it should not derive -/// PartialEq. -#[repr(C)] -pub struct ShouldNotDerivePartialEq { - pub a: BlocklistMe, -} -#[test] -fn bindgen_test_layout_ShouldNotDerivePartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ShouldNotDerivePartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ShouldNotDerivePartialEq)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotDerivePartialEq), - "::", - stringify!(a) - ) - ); -} -impl Default for ShouldNotDerivePartialEq { - 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/tests/expectations/tests/derive-partialeq-anonfield.rs b/tests/expectations/tests/derive-partialeq-anonfield.rs deleted file mode 100644 index 16d4381f86..0000000000 --- a/tests/expectations/tests/derive-partialeq-anonfield.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -pub struct rte_mbuf { - pub __bindgen_anon_1: rte_mbuf__bindgen_ty_1, -} -#[repr(C)] -#[repr(align(1))] -#[derive(Copy, Clone)] -pub struct rte_mbuf__bindgen_ty_1 { - pub bindgen_union_field: [u8; 0usize], -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_1)) - ); -} -impl Default for rte_mbuf__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() - } - } -} -#[test] -fn bindgen_test_layout_rte_mbuf() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(rte_mbuf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_mbuf)) - ); -} -impl Default for rte_mbuf { - 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/tests/expectations/tests/derive-partialeq-base.rs b/tests/expectations/tests/derive-partialeq-base.rs deleted file mode 100644 index cdf8dff8b4..0000000000 --- a/tests/expectations/tests/derive-partialeq-base.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Base { - pub large: [::std::os::raw::c_int; 33usize], -} -#[test] -fn bindgen_test_layout_Base() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(Base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Base)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).large as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Base), - "::", - stringify!(large) - ) - ); -} -impl Default for Base { - 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 Base { - fn eq(&self, other: &Base) -> bool { - &self.large[..] == &other.large[..] - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ShouldDerivePartialEq { - pub _base: Base, -} -#[test] -fn bindgen_test_layout_ShouldDerivePartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(ShouldDerivePartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ShouldDerivePartialEq)) - ); -} -impl Default for ShouldDerivePartialEq { - 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 ShouldDerivePartialEq { - fn eq(&self, other: &ShouldDerivePartialEq) -> bool { - self._base == other._base - } -} diff --git a/tests/expectations/tests/derive-partialeq-bitfield.rs b/tests/expectations/tests/derive-partialeq-bitfield.rs deleted file mode 100644 index cffffca57c..0000000000 --- a/tests/expectations/tests/derive-partialeq-bitfield.rs +++ /dev/null @@ -1,186 +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 const 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)] -#[derive(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() { - assert_eq!( - ::std::mem::size_of::(), - 204usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(large_array) - ) - ); -} -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 ::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 { - 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 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 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/tests/expectations/tests/derive-partialeq-core.rs b/tests/expectations/tests/derive-partialeq-core.rs deleted file mode 100644 index 8cdfb92c6a..0000000000 --- a/tests/expectations/tests/derive-partialeq-core.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate core; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct C { - pub large_array: [::std::os::raw::c_int; 420usize], -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::core::mem::size_of::(), - 1680usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).large_array as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(large_array) - ) - ); -} -impl Default for C { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -impl ::core::cmp::PartialEq for C { - fn eq(&self, other: &C) -> bool { - &self.large_array[..] == &other.large_array[..] - } -} diff --git a/tests/expectations/tests/derive-partialeq-pointer.rs b/tests/expectations/tests/derive-partialeq-pointer.rs deleted file mode 100644 index 17a5edcbbf..0000000000 --- a/tests/expectations/tests/derive-partialeq-pointer.rs +++ /dev/null @@ -1,125 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Bar { - pub b: *mut a, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(b)) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct c { - pub __bindgen_anon_1: c__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union c__bindgen_ty_1 { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_c__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(c__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(c__bindgen_ty_1)) - ); -} -impl Default for c__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() - } - } -} -#[test] -fn bindgen_test_layout_c() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(c)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(c)) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct a { - pub d: c, -} -#[test] -fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::
(), - 1usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(d)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/derive-partialeq-union.rs b/tests/expectations/tests/derive-partialeq-union.rs deleted file mode 100644 index b97c053198..0000000000 --- a/tests/expectations/tests/derive-partialeq-union.rs +++ /dev/null @@ -1,62 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// Deriving PartialEq for rust unions is not supported. -#[repr(C)] -#[derive(Copy, Clone)] -pub union ShouldNotDerivePartialEq { - pub a: ::std::os::raw::c_char, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ShouldNotDerivePartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(ShouldNotDerivePartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ShouldNotDerivePartialEq)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotDerivePartialEq), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotDerivePartialEq), - "::", - stringify!(b) - ) - ); -} -impl Default for ShouldNotDerivePartialEq { - 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/tests/expectations/tests/derive-partialeq-union_1_0.rs b/tests/expectations/tests/derive-partialeq-union_1_0.rs deleted file mode 100644 index 2098849f99..0000000000 --- a/tests/expectations/tests/derive-partialeq-union_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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 152usize, - concat!("Size of: ", stringify!(ShouldDerivePartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ShouldDerivePartialEq)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldDerivePartialEq), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldDerivePartialEq), - "::", - stringify!(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/tests/expectations/tests/disable-namespacing.rs b/tests/expectations/tests/disable-namespacing.rs deleted file mode 100644 index 626bb060c5..0000000000 --- a/tests/expectations/tests/disable-namespacing.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Baz = ::std::os::raw::c_int; diff --git a/tests/expectations/tests/disable-nested-struct-naming.rs b/tests/expectations/tests/disable-nested-struct-naming.rs deleted file mode 100644 index a9ad26a50a..0000000000 --- a/tests/expectations/tests/disable-nested-struct-naming.rs +++ /dev/null @@ -1,262 +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 b1: bar1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct bar1 { - pub x1: ::std::os::raw::c_int, - pub b2: bar1__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct bar1__bindgen_ty_1 { - pub x2: ::std::os::raw::c_int, - pub b3: bar1__bindgen_ty_1__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct bar1__bindgen_ty_1__bindgen_ty_1 { - pub x3: ::std::os::raw::c_int, - pub b4: bar4, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct bar4 { - pub x4: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_bar4() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar4)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x4 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(bar4), "::", stringify!(x4)) - ); -} -#[test] -fn bindgen_test_layout_bar1__bindgen_ty_1__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(bar1__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(bar1__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x3 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar1__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(x3) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b4 - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(bar1__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(b4) - ) - ); -} -#[test] -fn bindgen_test_layout_bar1__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(bar1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x2 as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar1__bindgen_ty_1), - "::", - stringify!(x2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b3 as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(bar1__bindgen_ty_1), - "::", - stringify!(b3) - ) - ); -} -#[test] -fn bindgen_test_layout_bar1() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(bar1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar1)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x1 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(bar1), "::", stringify!(x1)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b2 as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(bar1), "::", stringify!(b2)) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b1 as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b1)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct _bindgen_ty_1 { - pub anon2: _bindgen_ty_1__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct _bindgen_ty_1__bindgen_ty_1 { - pub b: baz, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct baz { - pub x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(baz), "::", stringify!(x)) - ); -} -#[test] -fn bindgen_test_layout__bindgen_ty_1__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1__bindgen_ty_1>(), - 4usize, - concat!("Size of: ", stringify!(_bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1__bindgen_ty_1>(), - 4usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_bindgen_ty_1__bindgen_ty_1>())).b - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1>(), - 4usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1>(), - 4usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_bindgen_ty_1>())).anon2 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(anon2) - ) - ); -} -extern "C" { - pub static mut anon1: _bindgen_ty_1; -} diff --git a/tests/expectations/tests/disable-untagged-union.rs b/tests/expectations/tests/disable-untagged-union.rs deleted file mode 100644 index 5300273384..0000000000 --- a/tests/expectations/tests/disable-untagged-union.rs +++ /dev/null @@ -1,80 +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 const 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::new() - } -} -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)] -pub struct Foo { - pub bar: __BindgenUnionField<::std::os::raw::c_int>, - pub baz: __BindgenUnionField<::std::os::raw::c_uint>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(baz)) - ); -} diff --git a/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/tests/expectations/tests/divide-by-zero-in-struct-layout.rs deleted file mode 100644 index 721d71e259..0000000000 --- a/tests/expectations/tests/divide-by-zero-in-struct-layout.rs +++ /dev/null @@ -1,138 +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 const 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)] -#[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, -} -impl WithBitfield { - #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit - } -} -#[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, -} -impl WithBitfieldAndAttrPacked { - #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit - } -} -#[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, -} -impl WithBitfieldAndPacked { - #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/do-not-derive-copy.rs b/tests/expectations/tests/do-not-derive-copy.rs deleted file mode 100644 index 4112d88a5c..0000000000 --- a/tests/expectations/tests/do-not-derive-copy.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct WouldBeCopyButWeAreNotDerivingCopy { - pub x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_WouldBeCopyButWeAreNotDerivingCopy() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WouldBeCopyButWeAreNotDerivingCopy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(WouldBeCopyButWeAreNotDerivingCopy) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WouldBeCopyButWeAreNotDerivingCopy), - "::", - stringify!(x) - ) - ); -} diff --git a/tests/expectations/tests/doggo-or-null.rs b/tests/expectations/tests/doggo-or-null.rs deleted file mode 100644 index fa7a5e89dc..0000000000 --- a/tests/expectations/tests/doggo-or-null.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq)] -pub struct Doggo { - pub x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Doggo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Doggo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Doggo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Doggo), "::", stringify!(x)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq)] -pub struct Null { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Null() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Null)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Null)) - ); -} -/// This type is an opaque union. Unions can't derive anything interesting like -/// Debug or Default, even if their layout can, because it would require knowing -/// which variant is in use. Opaque unions still end up as a `union` in the Rust -/// bindings, but they just have one variant. Even so, can't derive. We should -/// probably emit an opaque struct for opaque unions... but until then, we have -/// this test to make sure that opaque unions don't derive and still compile. -#[repr(C)] -#[repr(align(4))] -#[derive(Copy, Clone)] -pub union DoggoOrNull { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_DoggoOrNull() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(DoggoOrNull)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(DoggoOrNull)) - ); -} -impl Default for DoggoOrNull { - 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/tests/expectations/tests/duplicated-namespaces-definitions.rs b/tests/expectations/tests/duplicated-namespaces-definitions.rs deleted file mode 100644 index 324fe2a0a7..0000000000 --- a/tests/expectations/tests/duplicated-namespaces-definitions.rs +++ /dev/null @@ -1,102 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar { - pub foo: ::std::os::raw::c_int, - pub baz: bool, - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(foo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz) - ) - ); - } - } - pub mod bar { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Foo { - pub ptr: *mut root::foo::Bar, - } - #[test] - fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ptr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(ptr) - ) - ); - } - 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() - } - } - } - } -} diff --git a/tests/expectations/tests/duplicated-namespaces.rs b/tests/expectations/tests/duplicated-namespaces.rs deleted file mode 100644 index 0bbceac8e2..0000000000 --- a/tests/expectations/tests/duplicated-namespaces.rs +++ /dev/null @@ -1,12 +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 { - #[allow(unused_imports)] - use self::super::root; -} diff --git a/tests/expectations/tests/dynamic_loading_template.rs b/tests/expectations/tests/dynamic_loading_template.rs deleted file mode 100644 index 06e67ed791..0000000000 --- a/tests/expectations/tests/dynamic_loading_template.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate libloading; -pub struct TestLib { - __library: ::libloading::Library, - pub foo: Result< - unsafe extern "C" fn(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int, - ::libloading::Error, - >, - pub foo1: Result f32, ::libloading::Error>, -} -impl TestLib { - pub unsafe fn new

(path: P) -> Result - where - P: AsRef<::std::ffi::OsStr>, - { - let library = ::libloading::Library::new(path)?; - Self::from_library(library) - } - pub unsafe fn from_library( - library: L, - ) -> Result - where - 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); - Ok(TestLib { - __library, - foo, - foo1, - }) - } - pub unsafe fn foo( - &self, - x: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int { - (self.foo.as_ref().expect("Expected function, got error."))(x) - } - pub unsafe fn foo1(&self, x: f32) -> f32 { - (self.foo1.as_ref().expect("Expected function, got error."))(x) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_allowlist.rs b/tests/expectations/tests/dynamic_loading_with_allowlist.rs deleted file mode 100644 index 97bb67abdc..0000000000 --- a/tests/expectations/tests/dynamic_loading_with_allowlist.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate libloading; -pub struct TestLib { - __library: ::libloading::Library, - pub foo: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, - pub baz: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, - pub bazz: Result< - unsafe extern "C" fn( - arg1: ::std::os::raw::c_int, - ... - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, -} -impl TestLib { - pub unsafe fn new

(path: P) -> Result - where - P: AsRef<::std::ffi::OsStr>, - { - let library = ::libloading::Library::new(path)?; - Self::from_library(library) - } - pub unsafe fn from_library( - library: L, - ) -> Result - where - 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); - Ok(TestLib { - __library, - foo, - baz, - bazz, - }) - } - pub unsafe fn foo( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { - (self.foo.as_ref().expect("Expected function, got error."))(x) - } - pub unsafe fn baz( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { - (self.baz.as_ref().expect("Expected function, got error."))(x) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_blocklist.rs b/tests/expectations/tests/dynamic_loading_with_blocklist.rs deleted file mode 100644 index b06a6cf809..0000000000 --- a/tests/expectations/tests/dynamic_loading_with_blocklist.rs +++ /dev/null @@ -1,110 +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 X { - pub _x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_X() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(X)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(X)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::()))._x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(X), "::", stringify!(_x)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1X13some_functionEv"] - pub fn X_some_function(this: *mut X); -} -extern "C" { - #[link_name = "\u{1}_ZN1X19some_other_functionEv"] - pub fn X_some_other_function(this: *mut X); -} -extern "C" { - #[link_name = "\u{1}_ZN1XC1Ei"] - pub fn X_X(this: *mut X, x: ::std::os::raw::c_int); -} -impl X { - #[inline] - pub unsafe fn some_function(&mut self) { - X_some_function(self) - } - #[inline] - pub unsafe fn some_other_function(&mut self) { - X_some_other_function(self) - } - #[inline] - pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - X_X(__bindgen_tmp.as_mut_ptr(), x); - __bindgen_tmp.assume_init() - } -} -extern crate libloading; -pub struct TestLib { - __library: ::libloading::Library, - pub foo: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, - pub bar: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, -} -impl TestLib { - pub unsafe fn new

(path: P) -> Result - where - P: AsRef<::std::ffi::OsStr>, - { - let library = ::libloading::Library::new(path)?; - Self::from_library(library) - } - pub unsafe fn from_library( - library: L, - ) -> Result - where - 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); - Ok(TestLib { - __library, - foo, - bar, - }) - } - pub unsafe fn foo( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { - (self.foo.as_ref().expect("Expected function, got error."))(x) - } - pub unsafe fn bar( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { - (self.bar.as_ref().expect("Expected function, got error."))(x) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_class.rs b/tests/expectations/tests/dynamic_loading_with_class.rs deleted file mode 100644 index 8a66dc3f9a..0000000000 --- a/tests/expectations/tests/dynamic_loading_with_class.rs +++ /dev/null @@ -1,102 +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 A { - pub _x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::()))._x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(_x)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1A13some_functionEv"] - pub fn A_some_function(this: *mut A); -} -extern "C" { - #[link_name = "\u{1}_ZN1A19some_other_functionEv"] - pub fn A_some_other_function(this: *mut A); -} -extern "C" { - #[link_name = "\u{1}_ZN1AC1Ei"] - pub fn A_A(this: *mut A, x: ::std::os::raw::c_int); -} -impl A { - #[inline] - pub unsafe fn some_function(&mut self) { - A_some_function(self) - } - #[inline] - pub unsafe fn some_other_function(&mut self) { - A_some_other_function(self) - } - #[inline] - pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - A_A(__bindgen_tmp.as_mut_ptr(), x); - __bindgen_tmp.assume_init() - } -} -extern crate libloading; -pub struct TestLib { - __library: ::libloading::Library, - pub foo: Result< - unsafe extern "C" fn( - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - ::libloading::Error, - >, - pub bar: Result, -} -impl TestLib { - pub unsafe fn new

(path: P) -> Result - where - P: AsRef<::std::ffi::OsStr>, - { - let library = ::libloading::Library::new(path)?; - Self::from_library(library) - } - pub unsafe fn from_library( - library: L, - ) -> Result - where - 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); - Ok(TestLib { - __library, - foo, - bar, - }) - } - pub unsafe fn foo( - &self, - x: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int { - (self.foo.as_ref().expect("Expected function, got error."))(x) - } - pub unsafe fn bar(&self) -> () { - (self.bar.as_ref().expect("Expected function, got error."))() - } -} diff --git a/tests/expectations/tests/elaborated.rs b/tests/expectations/tests/elaborated.rs deleted file mode 100644 index 4741601640..0000000000 --- a/tests/expectations/tests/elaborated.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![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" { - #[link_name = "\u{1}_Z9somethingPKi"] - pub fn something(wat: *const whatever_whatever_t); -} diff --git a/tests/expectations/tests/empty_template_param_name.rs b/tests/expectations/tests/empty_template_param_name.rs deleted file mode 100644 index aa751f77e6..0000000000 --- a/tests/expectations/tests/empty_template_param_name.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type __void_t = ::std::os::raw::c_void; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct __iterator_traits { - pub _address: u8, -} diff --git a/tests/expectations/tests/enum-default-consts.rs b/tests/expectations/tests/enum-default-consts.rs deleted file mode 100644 index 5c023a3c64..0000000000 --- a/tests/expectations/tests/enum-default-consts.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub member: foo__bindgen_ty_1, -} -pub const foo_FOO_A: ::std::os::raw::c_uint = 0; -pub const foo_FOO_B: ::std::os::raw::c_uint = 1; -pub type foo__bindgen_ty_1 = ::std::os::raw::c_uint; -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} -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() - } - } -} -pub const Foo_Bar: Foo = 0; -pub const Foo_Qux: Foo = 1; -pub type Foo = ::std::os::raw::c_uint; -pub mod Neg { - pub type Type = ::std::os::raw::c_int; - pub const MinusOne: Type = -1; - pub const One: Type = 1; -} -pub const NoDebug_NoDebug1: NoDebug = 0; -pub const NoDebug_NoDebug2: NoDebug = 1; -///

-pub type NoDebug = ::std::os::raw::c_uint; -pub const Debug_Debug1: Debug = 0; -pub const Debug_Debug2: Debug = 1; -///
-pub type Debug = ::std::os::raw::c_uint; \ No newline at end of file diff --git a/tests/expectations/tests/enum-default-module.rs b/tests/expectations/tests/enum-default-module.rs deleted file mode 100644 index 156bbcaad0..0000000000 --- a/tests/expectations/tests/enum-default-module.rs +++ /dev/null @@ -1,71 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub member: foo__bindgen_ty_1::Type, -} -pub mod foo__bindgen_ty_1 { - pub type Type = ::std::os::raw::c_uint; - pub const FOO_A: Type = 0; - pub const FOO_B: Type = 1; -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} -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() - } - } -} -pub mod Foo { - pub type Type = ::std::os::raw::c_uint; - pub const Bar: Type = 0; - pub const Qux: Type = 1; -} -pub mod Neg { - pub type Type = ::std::os::raw::c_int; - pub const MinusOne: Type = -1; - pub const One: Type = 1; -} -pub mod NoDebug { - ///
- pub type Type = ::std::os::raw::c_uint; - pub const NoDebug1: Type = 0; - pub const NoDebug2: Type = 1; -} -pub mod Debug { - ///
- pub type Type = ::std::os::raw::c_uint; - pub const Debug1: Type = 0; - pub const Debug2: Type = 1; -} \ No newline at end of file diff --git a/tests/expectations/tests/enum-default-rust.rs b/tests/expectations/tests/enum-default-rust.rs deleted file mode 100644 index 045330a823..0000000000 --- a/tests/expectations/tests/enum-default-rust.rs +++ /dev/null @@ -1,77 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub member: foo__bindgen_ty_1, -} -pub const foo_FOO_A: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_A; -pub const foo_FOO_B: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_B; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum foo__bindgen_ty_1 { - FOO_A = 0, - FOO_B = 1, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} -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() - } - } -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - Bar = 0, - Qux = 1, -} -pub mod Neg { - pub type Type = ::std::os::raw::c_int; - pub const MinusOne: Type = -1; - pub const One: Type = 1; -} -#[repr(u32)] -///
-#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub enum NoDebug { - NoDebug1 = 0, - NoDebug2 = 1, -} -#[repr(u32)] -///
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Debug { - Debug1 = 0, - Debug2 = 1, -} \ No newline at end of file diff --git a/tests/expectations/tests/enum-doc-bitfield.rs b/tests/expectations/tests/enum-doc-bitfield.rs deleted file mode 100644 index 3be0438e5b..0000000000 --- a/tests/expectations/tests/enum-doc-bitfield.rs +++ /dev/null @@ -1,64 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -impl B { - /// Document field with three slashes - pub const VAR_A: B = B(0); -} -impl B { - /// Document field with preceeding star - pub const VAR_B: B = B(1); -} -impl B { - /// Document field with preceeding 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 preceeding star, with a loong long multiline - /// comment. - /// - /// Very interesting documentation, definitely. - pub const VAR_F: B = B(5); -} -impl ::std::ops::BitOr for B { - type Output = Self; - #[inline] - fn bitor(self, other: Self) -> Self { - B(self.0 | other.0) - } -} -impl ::std::ops::BitOrAssign for B { - #[inline] - fn bitor_assign(&mut self, rhs: B) { - self.0 |= rhs.0; - } -} -impl ::std::ops::BitAnd for B { - type Output = Self; - #[inline] - fn bitand(self, other: Self) -> Self { - B(self.0 & other.0) - } -} -impl ::std::ops::BitAndAssign for B { - #[inline] - fn bitand_assign(&mut self, rhs: B) { - self.0 &= rhs.0; - } -} -#[repr(transparent)] -/// Document enum -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct B(pub ::std::os::raw::c_uint); diff --git a/tests/expectations/tests/enum-doc-mod.rs b/tests/expectations/tests/enum-doc-mod.rs deleted file mode 100644 index 60d6b9f4d9..0000000000 --- a/tests/expectations/tests/enum-doc-mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod B { - /// Document enum - pub type Type = ::std::os::raw::c_uint; - /// Document field with three slashes - pub const VAR_A: Type = 0; - /// Document field with preceeding star - pub const VAR_B: Type = 1; - /// Document field with preceeding exclamation - pub const VAR_C: Type = 2; - ///< Document field with following star - pub const VAR_D: Type = 3; - ///< Document field with following exclamation - pub const VAR_E: Type = 4; - /// Document field with preceeding star, with a loong long multiline - /// comment. - /// - /// Very interesting documentation, definitely. - pub const VAR_F: Type = 5; -} diff --git a/tests/expectations/tests/enum-doc-rusty.rs b/tests/expectations/tests/enum-doc-rusty.rs deleted file mode 100644 index e7208a9db6..0000000000 --- a/tests/expectations/tests/enum-doc-rusty.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(u32)] -/// Document enum -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum B { - /// Document field with three slashes - VAR_A = 0, - /// Document field with preceeding star - VAR_B = 1, - /// Document field with preceeding exclamation - VAR_C = 2, - ///< Document field with following star - VAR_D = 3, - ///< Document field with following exclamation - VAR_E = 4, - /// Document field with preceeding star, with a loong long multiline - /// comment. - /// - /// Very interesting documentation, definitely. - VAR_F = 5, -} diff --git a/tests/expectations/tests/enum-doc.rs b/tests/expectations/tests/enum-doc.rs deleted file mode 100644 index b5d14b3cf0..0000000000 --- a/tests/expectations/tests/enum-doc.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// Document field with three slashes -pub const B_VAR_A: B = 0; -/// Document field with preceeding star -pub const B_VAR_B: B = 1; -/// Document field with preceeding exclamation -pub const B_VAR_C: B = 2; -///< Document field with following star -pub const B_VAR_D: B = 3; -///< Document field with following exclamation -pub const B_VAR_E: B = 4; -/// Document field with preceeding star, with a loong long multiline -/// comment. -/// -/// Very interesting documentation, definitely. -pub const B_VAR_F: B = 5; -/// Document enum -pub type B = ::std::os::raw::c_uint; diff --git a/tests/expectations/tests/enum-no-debug-rust.rs b/tests/expectations/tests/enum-no-debug-rust.rs deleted file mode 100644 index dbcbd052cc..0000000000 --- a/tests/expectations/tests/enum-no-debug-rust.rs +++ /dev/null @@ -1,77 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct foo { - pub member: foo__bindgen_ty_1, -} -pub const foo_FOO_A: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_A; -pub const foo_FOO_B: foo__bindgen_ty_1 = foo__bindgen_ty_1::FOO_B; -#[repr(u32)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub enum foo__bindgen_ty_1 { - FOO_A = 0, - FOO_B = 1, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} -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() - } - } -} -#[repr(u32)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - Bar = 0, - Qux = 1, -} -pub mod Neg { - pub type Type = ::std::os::raw::c_int; - pub const MinusOne: Type = -1; - pub const One: Type = 1; -} -#[repr(u32)] -///
-#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub enum NoDebug { - NoDebug1 = 0, - NoDebug2 = 1, -} -#[repr(u32)] -///
-#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] -pub enum Debug { - Debug1 = 0, - Debug2 = 1, -} diff --git a/tests/expectations/tests/enum-translate-type.rs b/tests/expectations/tests/enum-translate-type.rs deleted file mode 100644 index 89e6003e44..0000000000 --- a/tests/expectations/tests/enum-translate-type.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const my_enum1_A: my_enum1 = 0; -pub type my_enum1 = u32; -pub const my_enum2_B: my_enum2 = -1; -pub type my_enum2 = i32; -pub const my_enum3_C: my_enum3 = 0; -pub type my_enum3 = i16; -pub const my_enum4_D: my_enum4 = 255; -pub type my_enum4 = u8; diff --git a/tests/expectations/tests/enum-undefault.rs b/tests/expectations/tests/enum-undefault.rs deleted file mode 100644 index e5618b9148..0000000000 --- a/tests/expectations/tests/enum-undefault.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - Bar = 0, - Qux = 1, -} -pub const Neg_MinusOne: Neg = -1; -pub const Neg_One: Neg = 1; -pub type Neg = ::std::os::raw::c_int; diff --git a/tests/expectations/tests/enum-variant-replaces.rs b/tests/expectations/tests/enum-variant-replaces.rs deleted file mode 100644 index d927657492..0000000000 --- a/tests/expectations/tests/enum-variant-replaces.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-/// -/// Should see PASS below. -pub const OGRErr_PASS: OGRErr = 0; -///
-/// -/// Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below. -pub const OGRErr_OGRERR_NONE: OGRErr = 1; -///
-pub type OGRErr = ::std::os::raw::c_uint; diff --git a/tests/expectations/tests/enum.rs b/tests/expectations/tests/enum.rs deleted file mode 100644 index cc3f4932ca..0000000000 --- a/tests/expectations/tests/enum.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub member: foo__bindgen_ty_1, -} -pub const foo_FOO_A: ::std::os::raw::c_uint = 0; -pub const foo_FOO_B: ::std::os::raw::c_uint = 1; -pub type foo__bindgen_ty_1 = ::std::os::raw::c_uint; -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(member) - ) - ); -} -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() - } - } -} -pub const Foo_Bar: Foo = 0; -pub const Foo_Qux: Foo = 1; -pub type Foo = ::std::os::raw::c_uint; -pub const Neg_MinusOne: Neg = -1; -pub const Neg_One: Neg = 1; -pub type Neg = ::std::os::raw::c_int; -pub const NoDebug_NoDebug1: NoDebug = 0; -pub const NoDebug_NoDebug2: NoDebug = 1; -///
-pub type NoDebug = ::std::os::raw::c_uint; -pub const Debug_Debug1: Debug = 0; -pub const Debug_Debug2: Debug = 1; -///
-pub type Debug = ::std::os::raw::c_uint; \ No newline at end of file diff --git a/tests/expectations/tests/enum_alias.rs b/tests/expectations/tests/enum_alias.rs deleted file mode 100644 index ad62d16fa2..0000000000 --- a/tests/expectations/tests/enum_alias.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(u8)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Bar { - VAL = 0, -} diff --git a/tests/expectations/tests/enum_and_vtable_mangling.rs b/tests/expectations/tests/enum_and_vtable_mangling.rs deleted file mode 100644 index 5ae76c4c29..0000000000 --- a/tests/expectations/tests/enum_and_vtable_mangling.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const match_: _bindgen_ty_1 = _bindgen_ty_1::match_; -pub const whatever_else: _bindgen_ty_1 = _bindgen_ty_1::whatever_else; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - match_ = 0, - whatever_else = 1, -} -#[repr(C)] -pub struct C__bindgen_vtable { - pub C_match: unsafe extern "C" fn(this: *mut C), -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct C { - pub vtable_: *const C__bindgen_vtable, - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(i)) - ); -} -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() - } - } -} -extern "C" { - #[link_name = "\u{1}_ZN1C5matchEv"] - pub fn C_match(this: *mut ::std::os::raw::c_void); -} diff --git a/tests/expectations/tests/enum_dupe.rs b/tests/expectations/tests/enum_dupe.rs deleted file mode 100644 index 869375bbfd..0000000000 --- a/tests/expectations/tests/enum_dupe.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -impl Foo { - pub const Dupe: Foo = Foo::Bar; -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - Bar = 1, -} diff --git a/tests/expectations/tests/enum_in_template.rs b/tests/expectations/tests/enum_in_template.rs deleted file mode 100644 index c4c06a3733..0000000000 --- a/tests/expectations/tests/enum_in_template.rs +++ /dev/null @@ -1,15 +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, -} -pub const Foo_Bar_A: Foo_Bar = 0; -pub const Foo_Bar_B: Foo_Bar = 0; -pub type Foo_Bar = i32; diff --git a/tests/expectations/tests/enum_negative.rs b/tests/expectations/tests/enum_negative.rs deleted file mode 100644 index 02b4baed59..0000000000 --- a/tests/expectations/tests/enum_negative.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - Bar = -2, - Qux = 1, -} diff --git a/tests/expectations/tests/eval-value-dependent.rs b/tests/expectations/tests/eval-value-dependent.rs deleted file mode 100644 index 3376bfc6b3..0000000000 --- a/tests/expectations/tests/eval-value-dependent.rs +++ /dev/null @@ -1,13 +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 e { - pub _address: u8, -} -pub type e_f = d; diff --git a/tests/expectations/tests/eval-variadic-template-parameter.rs b/tests/expectations/tests/eval-variadic-template-parameter.rs deleted file mode 100644 index 576bb721c5..0000000000 --- a/tests/expectations/tests/eval-variadic-template-parameter.rs +++ /dev/null @@ -1,12 +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 B { - pub _address: u8, -} diff --git a/tests/expectations/tests/explicit-padding.rs b/tests/expectations/tests/explicit-padding.rs deleted file mode 100644 index 3c429756c2..0000000000 --- a/tests/expectations/tests/explicit-padding.rs +++ /dev/null @@ -1,130 +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 pad_me { - pub first: u8, - pub __bindgen_padding_0: [u8; 3usize], - pub second: u32, - pub third: u16, - pub __bindgen_padding_1: [u8; 2usize], -} -#[test] -fn bindgen_test_layout_pad_me() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(pad_me)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(pad_me)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).first as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(pad_me), - "::", - stringify!(first) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).second as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(pad_me), - "::", - stringify!(second) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).third as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(pad_me), - "::", - stringify!(third) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union dont_pad_me { - pub first: u8, - pub second: u32, - pub third: u16, -} -#[test] -fn bindgen_test_layout_dont_pad_me() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(dont_pad_me)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(dont_pad_me)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).first as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(dont_pad_me), - "::", - stringify!(first) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).second as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(dont_pad_me), - "::", - stringify!(second) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).third as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(dont_pad_me), - "::", - stringify!(third) - ) - ); -} -impl Default for dont_pad_me { - 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/tests/expectations/tests/extern-const-struct.rs b/tests/expectations/tests/extern-const-struct.rs deleted file mode 100644 index fa0018ba90..0000000000 --- a/tests/expectations/tests/extern-const-struct.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct nsFoo { - pub details: [f32; 400usize], -} -#[test] -fn bindgen_test_layout_nsFoo() { - assert_eq!( - ::std::mem::size_of::(), - 1600usize, - concat!("Size of: ", stringify!(nsFoo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(nsFoo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).details as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsFoo), - "::", - stringify!(details) - ) - ); -} -impl Default for nsFoo { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - pub static gDetails: nsFoo; -} diff --git a/tests/expectations/tests/extern.rs b/tests/expectations/tests/extern.rs deleted file mode 100644 index 7ded13f179..0000000000 --- a/tests/expectations/tests/extern.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type foo = ::std::option::Option< - unsafe extern "C" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int, ->; diff --git a/tests/expectations/tests/float128.rs b/tests/expectations/tests/float128.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/float128.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/forward-declaration-autoptr.rs b/tests/expectations/tests/forward-declaration-autoptr.rs deleted file mode 100644 index bf0b6926f1..0000000000 --- a/tests/expectations/tests/forward-declaration-autoptr.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct RefPtr { - pub m_inner: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for RefPtr { - 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 Bar { - pub m_member: RefPtr, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).m_member as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(m_member) - ) - ); -} -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() - } - } -} -#[test] -fn __bindgen_test_layout_RefPtr_open0_Foo_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!("Size of template specialization: ", stringify!(RefPtr)) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(RefPtr) - ) - ); -} diff --git a/tests/expectations/tests/forward-enum-decl.rs b/tests/expectations/tests/forward-enum-decl.rs deleted file mode 100644 index 0ac550bcba..0000000000 --- a/tests/expectations/tests/forward-enum-decl.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum CSSPseudoClassType { - empty = 0, - link = 1, -} diff --git a/tests/expectations/tests/forward_declared_complex_types.rs b/tests/expectations/tests/forward_declared_complex_types.rs deleted file mode 100644 index e185e83064..0000000000 --- a/tests/expectations/tests/forward_declared_complex_types.rs +++ /dev/null @@ -1,84 +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_empty { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Foo_empty() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo_empty)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo_empty)) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Bar { - pub f: *mut Foo, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(f)) - ); -} -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() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z10baz_structP3Foo"] - pub fn baz_struct(f: *mut Foo); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Union { - _unused: [u8; 0], -} -extern "C" { - #[link_name = "\u{1}_Z9baz_unionP5Union"] - pub fn baz_union(u: *mut Union); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Quux { - _unused: [u8; 0], -} -extern "C" { - #[link_name = "\u{1}_Z9baz_classP4Quux"] - pub fn baz_class(q: *mut Quux); -} diff --git a/tests/expectations/tests/forward_declared_complex_types_1_0.rs b/tests/expectations/tests/forward_declared_complex_types_1_0.rs deleted file mode 100644 index c6331c6941..0000000000 --- a/tests/expectations/tests/forward_declared_complex_types_1_0.rs +++ /dev/null @@ -1,109 +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, - concat!("Size of: ", stringify!(Foo_empty)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(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/tests/expectations/tests/forward_declared_opaque.rs b/tests/expectations/tests/forward_declared_opaque.rs deleted file mode 100644 index 58c02b4406..0000000000 --- a/tests/expectations/tests/forward_declared_opaque.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct a { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct b { - _unused: [u8; 0], -} diff --git a/tests/expectations/tests/forward_declared_struct.rs b/tests/expectations/tests/forward_declared_struct.rs deleted file mode 100644 index 2ecfc60ed6..0000000000 --- a/tests/expectations/tests/forward_declared_struct.rs +++ /dev/null @@ -1,53 +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 a { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::
(), - 4usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(b)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct c { - pub d: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_c() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(c)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(c)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(c), "::", stringify!(d)) - ); -} diff --git a/tests/expectations/tests/func_proto.rs b/tests/expectations/tests/func_proto.rs deleted file mode 100644 index 7ded13f179..0000000000 --- a/tests/expectations/tests/func_proto.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type foo = ::std::option::Option< - unsafe extern "C" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int, ->; diff --git a/tests/expectations/tests/func_ptr.rs b/tests/expectations/tests/func_ptr.rs deleted file mode 100644 index 9c718f03ec..0000000000 --- a/tests/expectations/tests/func_ptr.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub static mut foo: ::std::option::Option< - unsafe extern "C" fn( - x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, - >; -} diff --git a/tests/expectations/tests/func_ptr_in_struct.rs b/tests/expectations/tests/func_ptr_in_struct.rs deleted file mode 100644 index 8f98763fbc..0000000000 --- a/tests/expectations/tests/func_ptr_in_struct.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum baz { - __bindgen_cannot_repr_c_on_empty_enum = 0, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Foo { - pub bar: ::std::option::Option< - unsafe extern "C" fn( - x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, - ) -> baz, - >, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/func_ptr_return_type.rs b/tests/expectations/tests/func_ptr_return_type.rs deleted file mode 100644 index 8f2da8efda..0000000000 --- a/tests/expectations/tests/func_ptr_return_type.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn func() -> ::std::option::Option< - unsafe extern "C" fn( - arg1: ::std::os::raw::c_int, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, - >; -} diff --git a/tests/expectations/tests/func_with_array_arg.rs b/tests/expectations/tests/func_with_array_arg.rs deleted file mode 100644 index f98192f8db..0000000000 --- a/tests/expectations/tests/func_with_array_arg.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn f(x: *mut ::std::os::raw::c_int); -} diff --git a/tests/expectations/tests/func_with_func_ptr_arg.rs b/tests/expectations/tests/func_with_func_ptr_arg.rs deleted file mode 100644 index fb06b88e68..0000000000 --- a/tests/expectations/tests/func_with_func_ptr_arg.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(bar: ::std::option::Option); -} -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, - ), - >, - two: ::std::option::Option< - unsafe extern "C" fn( - c: ::std::os::raw::c_int, - d: ::std::os::raw::c_int, - ), - >, - ); -} diff --git a/tests/expectations/tests/gen-constructors-neg.rs b/tests/expectations/tests/gen-constructors-neg.rs deleted file mode 100644 index f5ba025a25..0000000000 --- a/tests/expectations/tests/gen-constructors-neg.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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/gen-constructors.rs b/tests/expectations/tests/gen-constructors.rs deleted file mode 100644 index 89b8637954..0000000000 --- a/tests/expectations/tests/gen-constructors.rs +++ /dev/null @@ -1,37 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3FooC1Ei"] - pub fn Foo_Foo(this: *mut Foo, a: ::std::os::raw::c_int); -} -impl Foo { - #[inline] - pub unsafe fn new(a: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Foo_Foo(__bindgen_tmp.as_mut_ptr(), a); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/gen-destructors-neg.rs b/tests/expectations/tests/gen-destructors-neg.rs deleted file mode 100644 index 67b6d70143..0000000000 --- a/tests/expectations/tests/gen-destructors-neg.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct Foo { - pub bar: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/gen-destructors.rs b/tests/expectations/tests/gen-destructors.rs deleted file mode 100644 index 7d96870df8..0000000000 --- a/tests/expectations/tests/gen-destructors.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct Foo { - pub bar: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3FooD1Ev"] - pub fn Foo_Foo_destructor(this: *mut Foo); -} -impl Foo { - #[inline] - pub unsafe fn destruct(&mut self) { - Foo_Foo_destructor(self) - } -} diff --git a/tests/expectations/tests/generate-inline.rs b/tests/expectations/tests/generate-inline.rs deleted file mode 100644 index 3cb865a4d7..0000000000 --- a/tests/expectations/tests/generate-inline.rs +++ /dev/null @@ -1,39 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo3barEv"] - pub fn Foo_bar() -> ::std::os::raw::c_int; -} -impl Foo { - #[inline] - pub unsafe fn bar() -> ::std::os::raw::c_int { - Foo_bar() - } -} -extern "C" { - #[link_name = "\u{1}_Z3foov"] - pub fn foo() -> ::std::os::raw::c_int; -} diff --git a/tests/expectations/tests/i128.rs b/tests/expectations/tests/i128.rs deleted file mode 100644 index 1a239694c4..0000000000 --- a/tests/expectations/tests/i128.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(16))] -#[derive(Debug, Default, Copy, Clone)] -pub struct foo { - pub my_signed: i128, - pub my_unsigned: u128, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).my_signed as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(my_signed) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).my_unsigned as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(my_unsigned) - ) - ); -} diff --git a/tests/expectations/tests/in_class_typedef.rs b/tests/expectations/tests/in_class_typedef.rs deleted file mode 100644 index 7bb7d39182..0000000000 --- a/tests/expectations/tests/in_class_typedef.rs +++ /dev/null @@ -1,20 +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, -} -pub type Foo_elem_type = T; -pub type Foo_ptr_type = *mut T; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo_Bar { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} diff --git a/tests/expectations/tests/incomplete-array-padding.rs b/tests/expectations/tests/incomplete-array-padding.rs deleted file mode 100644 index 18061ea12a..0000000000 --- a/tests/expectations/tests/incomplete-array-padding.rs +++ /dev/null @@ -1,179 +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 const 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)] -#[derive(Default)] -pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); -impl __IncompleteArrayField { - #[inline] - pub const 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)] -#[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>, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); -} -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 a(&self) -> ::std::os::raw::c_char { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - a: ::std::os::raw::c_char, - ) -> __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 - } -} diff --git a/tests/expectations/tests/infinite-macro.rs b/tests/expectations/tests/infinite-macro.rs deleted file mode 100644 index 081a0c296b..0000000000 --- a/tests/expectations/tests/infinite-macro.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const INFINITY: f64 = ::std::f64::INFINITY; -pub const NAN: f64 = ::std::f64::NAN; diff --git a/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs b/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs deleted file mode 100644 index 0876878efc..0000000000 --- a/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs +++ /dev/null @@ -1,238 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct BaseWithVtable__bindgen_vtable {} -/// This should have an explicit vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct BaseWithVtable { - pub vtable_: *const BaseWithVtable__bindgen_vtable, - pub t: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for BaseWithVtable { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// This should not have an explicit vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DerivedWithNoVirtualMethods { - pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DerivedWithNoVirtualMethods() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(DerivedWithNoVirtualMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(DerivedWithNoVirtualMethods)) - ); -} -impl Default for DerivedWithNoVirtualMethods { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// This should not have an explicit vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DerivedWithVirtualMethods { - pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DerivedWithVirtualMethods() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(DerivedWithVirtualMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(DerivedWithVirtualMethods)) - ); -} -impl Default for DerivedWithVirtualMethods { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// This should not have any vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct BaseWithoutVtable { - pub u: U, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for BaseWithoutVtable { - 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 DerivedWithVtable__bindgen_vtable(::std::os::raw::c_void); -/// This should have an explicit vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DerivedWithVtable { - pub vtable_: *const DerivedWithVtable__bindgen_vtable, - pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DerivedWithVtable() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(DerivedWithVtable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(DerivedWithVtable)) - ); -} -impl Default for DerivedWithVtable { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// This should not have any vtable. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DerivedWithoutVtable { - pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DerivedWithoutVtable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(DerivedWithoutVtable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(DerivedWithoutVtable)) - ); -} -impl Default for DerivedWithoutVtable { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_BaseWithVtable_open0_ptr_char_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 16usize, - concat!( - "Size of template specialization: ", - stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) - ) - ); -} -#[test] -fn __bindgen_test_layout_BaseWithVtable_open0_ptr_char_close0_instantiation_1() -{ - assert_eq!( - ::std::mem::size_of::>(), - 16usize, - concat!( - "Size of template specialization: ", - stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) - ) - ); -} -#[test] -fn __bindgen_test_layout_BaseWithoutVtable_open0_ptr_char_close0_instantiation() -{ - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) - ) - ); - assert_eq!( - ::std::mem::align_of::>( - ), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) - ) - ); -} -#[test] -fn __bindgen_test_layout_BaseWithoutVtable_open0_ptr_char_close0_instantiation_1( -) { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) - ) - ); - assert_eq!( - ::std::mem::align_of::>( - ), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) - ) - ); -} diff --git a/tests/expectations/tests/inherit_typedef.rs b/tests/expectations/tests/inherit_typedef.rs deleted file mode 100644 index 285dd44f1c..0000000000 --- a/tests/expectations/tests/inherit_typedef.rs +++ /dev/null @@ -1,44 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -pub type TypedefedFoo = Foo; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} diff --git a/tests/expectations/tests/inline-function.rs b/tests/expectations/tests/inline-function.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/inline-function.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/inline_namespace.rs b/tests/expectations/tests/inline_namespace.rs deleted file mode 100644 index 036d2da618..0000000000 --- a/tests/expectations/tests/inline_namespace.rs +++ /dev/null @@ -1,45 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - pub type Ty = ::std::os::raw::c_int; - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar { - pub baz: root::foo::Ty, - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz) - ) - ); - } -} diff --git a/tests/expectations/tests/inline_namespace_allowlist.rs b/tests/expectations/tests/inline_namespace_allowlist.rs deleted file mode 100644 index 1f4bc686c1..0000000000 --- a/tests/expectations/tests/inline_namespace_allowlist.rs +++ /dev/null @@ -1,17 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod std { - #[allow(unused_imports)] - use self::super::super::root; - pub type string = *const ::std::os::raw::c_char; - } -} diff --git a/tests/expectations/tests/inline_namespace_conservative.rs b/tests/expectations/tests/inline_namespace_conservative.rs deleted file mode 100644 index 3d2ce0c419..0000000000 --- a/tests/expectations/tests/inline_namespace_conservative.rs +++ /dev/null @@ -1,50 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - pub mod bar { - #[allow(unused_imports)] - use self::super::super::super::root; - pub type Ty = ::std::os::raw::c_int; - } - pub type Ty = ::std::os::raw::c_longlong; - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar { - pub baz: root::foo::bar::Ty, - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(baz) - ) - ); - } -} diff --git a/tests/expectations/tests/inner_const.rs b/tests/expectations/tests/inner_const.rs deleted file mode 100644 index 912ae02422..0000000000 --- a/tests/expectations/tests/inner_const.rs +++ /dev/null @@ -1,38 +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 bar: ::std::os::raw::c_int, -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo3BOOE"] - pub static mut Foo_BOO: ::std::os::raw::c_int; -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo8whateverE"] - pub static mut Foo_whatever: Foo; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/inner_template_self.rs b/tests/expectations/tests/inner_template_self.rs deleted file mode 100644 index 3361a1f9dd..0000000000 --- a/tests/expectations/tests/inner_template_self.rs +++ /dev/null @@ -1,78 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct LinkedList { - pub next: *mut LinkedList, - pub prev: *mut LinkedList, -} -impl Default for LinkedList { - 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 InstantiateIt { - pub m_list: LinkedList, -} -#[test] -fn bindgen_test_layout_InstantiateIt() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(InstantiateIt)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(InstantiateIt)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).m_list as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(InstantiateIt), - "::", - stringify!(m_list) - ) - ); -} -impl Default for InstantiateIt { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_LinkedList_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of template specialization: ", stringify!(LinkedList)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(LinkedList) - ) - ); -} diff --git a/tests/expectations/tests/int128_t.rs b/tests/expectations/tests/int128_t.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/int128_t.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/issue-1025-unknown-enum-repr.rs b/tests/expectations/tests/issue-1025-unknown-enum-repr.rs deleted file mode 100644 index c42e167fba..0000000000 --- a/tests/expectations/tests/issue-1025-unknown-enum-repr.rs +++ /dev/null @@ -1,13 +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 a { - pub _address: u8, -} -pub type a__bindgen_ty_1 = i32; diff --git a/tests/expectations/tests/issue-1034.rs b/tests/expectations/tests/issue-1034.rs deleted file mode 100644 index 32f4310e49..0000000000 --- a/tests/expectations/tests/issue-1034.rs +++ /dev/null @@ -1,120 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct S2 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, -} -#[test] -fn bindgen_test_layout_S2() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(S2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(S2)) - ); -} -impl S2 { - #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/issue-1040.rs b/tests/expectations/tests/issue-1040.rs deleted file mode 100644 index 8503e8d226..0000000000 --- a/tests/expectations/tests/issue-1040.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const g_107: ::std::os::raw::c_ulonglong = 18446744073709551615; diff --git a/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs b/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs deleted file mode 100644 index d91dd8fa5c..0000000000 --- a/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs +++ /dev/null @@ -1,120 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct S1 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, -} -#[test] -fn bindgen_test_layout_S1() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(S1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(S1)) - ); -} -impl S1 { - #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/issue-1118-using-forward-decl.rs b/tests/expectations/tests/issue-1118-using-forward-decl.rs deleted file mode 100644 index 99f0341c9d..0000000000 --- a/tests/expectations/tests/issue-1118-using-forward-decl.rs +++ /dev/null @@ -1,137 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type c = nsTArray; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct nsTArray_base { - pub d: *mut ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_nsTArray_base() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsTArray_base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsTArray_base)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsTArray_base), - "::", - stringify!(d) - ) - ); -} -impl Default for nsTArray_base { - 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 nsTArray { - pub _base: nsTArray_base, -} -impl Default for nsTArray { - 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 nsIContent { - pub foo: nsTArray, -} -#[test] -fn bindgen_test_layout_nsIContent() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsIContent)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsIContent)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsIContent), - "::", - stringify!(foo) - ) - ); -} -impl Default for nsIContent { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z35Gecko_GetAnonymousContentForElementv"] - pub fn Gecko_GetAnonymousContentForElement() -> *mut nsTArray; -} -#[test] -fn __bindgen_test_layout_nsTArray_open0_ptr_nsIContent_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of template specialization: ", stringify!(nsTArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(nsTArray) - ) - ); -} -#[test] -fn __bindgen_test_layout_nsTArray_open0_ptr_nsIContent_close0_instantiation_1() -{ - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of template specialization: ", stringify!(nsTArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(nsTArray) - ) - ); -} diff --git a/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs b/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs deleted file mode 100644 index fd023363d7..0000000000 --- a/tests/expectations/tests/issue-1197-pure-virtual-stuff.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Foo__bindgen_vtable(::std::os::raw::c_void); -#[repr(C)] -#[derive(Debug)] -pub struct Foo { - pub vtable_: *const Foo__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs b/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs deleted file mode 100644 index 81c74abbf0..0000000000 --- a/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod MyDupeEnum { - 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 { - pub type Type = ::std::os::raw::c_uint; - pub const C: Type = 0; - pub const C_alias: Type = 0; - pub const D: Type = 1; -} diff --git a/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs b/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs deleted file mode 100644 index 81c74abbf0..0000000000 --- a/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub mod MyDupeEnum { - 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 { - pub type Type = ::std::os::raw::c_uint; - pub const C: Type = 0; - pub const C_alias: Type = 0; - pub const D: Type = 1; -} diff --git a/tests/expectations/tests/issue-1216-variadic-member.rs b/tests/expectations/tests/issue-1216-variadic-member.rs deleted file mode 100644 index 5bca80966c..0000000000 --- a/tests/expectations/tests/issue-1216-variadic-member.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn f(a: ::std::os::raw::c_int, ...); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub f: ::std::option::Option< - unsafe extern "C" fn( - p: *mut ::std::os::raw::c_void, - obj: *mut ::std::os::raw::c_void, - a: ::std::os::raw::c_int, - ... - ), - >, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(f)) - ); -} diff --git a/tests/expectations/tests/issue-1238-fwd-no-copy.rs b/tests/expectations/tests/issue-1238-fwd-no-copy.rs deleted file mode 100644 index 006900cb6e..0000000000 --- a/tests/expectations/tests/issue-1238-fwd-no-copy.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug)] -pub struct MyType { - _unused: [u8; 0], -} -pub type MyTypeT = MyType; diff --git a/tests/expectations/tests/issue-1281.rs b/tests/expectations/tests/issue-1281.rs deleted file mode 100644 index fe18fb1a0a..0000000000 --- a/tests/expectations/tests/issue-1281.rs +++ /dev/null @@ -1,77 +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 bar { - pub u: foo, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct foo { - pub foo: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(foo)) - ); -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(bar), "::", stringify!(u)) - ); -} -pub type bar_t = bar; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct baz { - pub f: foo, -} -#[test] -fn bindgen_test_layout_baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(baz), "::", stringify!(f)) - ); -} diff --git a/tests/expectations/tests/issue-1285.rs b/tests/expectations/tests/issue-1285.rs deleted file mode 100644 index 15b8c9e449..0000000000 --- a/tests/expectations/tests/issue-1285.rs +++ /dev/null @@ -1,91 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_uint, - pub b: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/issue-1291.rs b/tests/expectations/tests/issue-1291.rs deleted file mode 100644 index 5680c348cf..0000000000 --- a/tests/expectations/tests/issue-1291.rs +++ /dev/null @@ -1,194 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(16))] -#[derive(Debug, Default, Copy, Clone)] -pub struct RTCRay { - pub org: [f32; 3usize], - pub align0: f32, - pub dir: [f32; 3usize], - pub align1: f32, - pub tnear: f32, - pub tfar: f32, - pub time: f32, - pub mask: ::std::os::raw::c_uint, - pub Ng: [f32; 3usize], - pub align2: f32, - pub u: f32, - pub v: f32, - pub geomID: ::std::os::raw::c_uint, - pub primID: ::std::os::raw::c_uint, - pub instID: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_RTCRay() { - assert_eq!( - ::std::mem::size_of::(), - 96usize, - concat!("Size of: ", stringify!(RTCRay)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(RTCRay)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).org as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(org) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).align0 as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(align0) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).dir as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(dir) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).align1 as *const _ as usize - }, - 28usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(align1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tnear as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(tnear) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).tfar as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(tfar) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).time as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(time) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mask as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(mask) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ng as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(Ng) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).align2 as *const _ as usize - }, - 60usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(align2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 64usize, - concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(u)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).v as *const _ as usize }, - 68usize, - concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(v)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).geomID as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(geomID) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).primID as *const _ as usize - }, - 76usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(primID) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).instID as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(RTCRay), - "::", - stringify!(instID) - ) - ); -} diff --git a/tests/expectations/tests/issue-1350-attribute-overloadable.rs b/tests/expectations/tests/issue-1350-attribute-overloadable.rs deleted file mode 100644 index 4deed06055..0000000000 --- a/tests/expectations/tests/issue-1350-attribute-overloadable.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z11my_functioni"] - pub fn my_function(a: ::std::os::raw::c_int); -} -extern "C" { - #[link_name = "\u{1}_Z11my_functionPKc"] - pub fn my_function1(a: *const ::std::os::raw::c_char); -} diff --git a/tests/expectations/tests/issue-1382-rust-primitive-types.rs b/tests/expectations/tests/issue-1382-rust-primitive-types.rs deleted file mode 100644 index 6f5aec4b6f..0000000000 --- a/tests/expectations/tests/issue-1382-rust-primitive-types.rs +++ /dev/null @@ -1,136 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type i8_ = i8; -pub type u8_ = u8; -pub type i16_ = i16; -pub type u16_ = u16; -pub type i32_ = i32; -pub type u32_ = u32; -pub type i64_ = i64; -pub type u64_ = u64; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub i8_: ::std::os::raw::c_int, - pub u8_: ::std::os::raw::c_int, - pub i16_: ::std::os::raw::c_int, - pub u16_: ::std::os::raw::c_int, - pub i32_: ::std::os::raw::c_int, - pub u32_: ::std::os::raw::c_int, - pub i64_: ::std::os::raw::c_int, - pub u64_: ::std::os::raw::c_int, - pub i128_: ::std::os::raw::c_int, - pub u128_: ::std::os::raw::c_int, - pub isize_: ::std::os::raw::c_int, - pub usize_: ::std::os::raw::c_int, - pub f32_: ::std::os::raw::c_int, - pub f64_: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 56usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i8_ as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(i8_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u8_ as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(u8_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i16_ as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(i16_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u16_ as *const _ as usize }, - 12usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(u16_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i32_ as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(i32_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u32_ as *const _ as usize }, - 20usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(u32_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i64_ as *const _ as usize }, - 24usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(i64_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u64_ as *const _ as usize }, - 28usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(u64_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i128_ as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(i128_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u128_ as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(u128_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).isize_ as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(isize_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).usize_ as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(usize_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f32_ as *const _ as usize }, - 48usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(f32_)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f64_ as *const _ as usize }, - 52usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(f64_)) - ); -} diff --git a/tests/expectations/tests/issue-1435.rs b/tests/expectations/tests/issue-1435.rs deleted file mode 100644 index 79ed7b294b..0000000000 --- a/tests/expectations/tests/issue-1435.rs +++ /dev/null @@ -1,24 +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 { - #[allow(unused_imports)] - use self::super::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 type AB = ::std::os::raw::c_int; - } - pub use self::super::root::ns::AB; - extern "C" { - #[link_name = "\u{1}_ZL2kA"] - pub static kA: root::AB; - } -} diff --git a/tests/expectations/tests/issue-1443.rs b/tests/expectations/tests/issue-1443.rs deleted file mode 100644 index f422f4c353..0000000000 --- a/tests/expectations/tests/issue-1443.rs +++ /dev/null @@ -1,164 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Bar { - pub f: *const Foo, - pub m: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(f)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(m)) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Baz { - pub f: *mut Foo, - pub m: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Baz), "::", stringify!(f)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Baz), "::", stringify!(m)) - ); -} -impl Default for Baz { - 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 Tar { - pub f: *const Foo, - pub m: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_Tar() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Tar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Tar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Tar), "::", stringify!(f)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Tar), "::", stringify!(m)) - ); -} -impl Default for Tar { - 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 Taz { - pub f: *mut Foo, - pub m: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_Taz() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Taz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Taz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Taz), "::", stringify!(f)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Taz), "::", stringify!(m)) - ); -} -impl Default for Taz { - 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/tests/expectations/tests/issue-1454.rs b/tests/expectations/tests/issue-1454.rs deleted file mode 100644 index e88e46978b..0000000000 --- a/tests/expectations/tests/issue-1454.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug)] -pub struct extern_type; - -#[repr(C)] -#[derive(Debug)] -pub struct local_type { - pub inner: extern_type, -} -#[test] -fn bindgen_test_layout_local_type() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(local_type)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(local_type)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).inner as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(local_type), - "::", - stringify!(inner) - ) - ); -} diff --git a/tests/expectations/tests/issue-1464.rs b/tests/expectations/tests/issue-1464.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/issue-1464.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/issue-1488-template-alias-new-type.rs b/tests/expectations/tests/issue-1488-template-alias-new-type.rs deleted file mode 100644 index 1af0c5751d..0000000000 --- a/tests/expectations/tests/issue-1488-template-alias-new-type.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(transparent)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Wrapped(pub T); diff --git a/tests/expectations/tests/issue-1498.rs b/tests/expectations/tests/issue-1498.rs deleted file mode 100644 index 4f8a89305b..0000000000 --- a/tests/expectations/tests/issue-1498.rs +++ /dev/null @@ -1,178 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type size_t = u64; -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct rte_memseg { - ///< Start physical address. - pub phys_addr: u64, - pub __bindgen_anon_1: rte_memseg__bindgen_ty_1, - ///< Length of the segment. - pub len: size_t, - ///< The pagesize of underlying memory - pub hugepage_sz: u64, - ///< NUMA socket ID. - pub socket_id: i32, - ///< Number of channels. - pub nchannel: u32, - ///< Number of ranks. - pub nrank: u32, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union rte_memseg__bindgen_ty_1 { - ///< Start virtual address. - pub addr: *mut ::std::os::raw::c_void, - ///< Makes sure addr is always 64 bits - pub addr_64: u64, -} -#[test] -fn bindgen_test_layout_rte_memseg__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_memseg__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_memseg__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).addr - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg__bindgen_ty_1), - "::", - stringify!(addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).addr_64 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg__bindgen_ty_1), - "::", - stringify!(addr_64) - ) - ); -} -impl Default for rte_memseg__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() - } - } -} -#[test] -fn bindgen_test_layout_rte_memseg() { - assert_eq!( - ::std::mem::size_of::(), - 44usize, - concat!("Size of: ", stringify!(rte_memseg)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(rte_memseg)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).phys_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(phys_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).len as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hugepage_sz as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(hugepage_sz) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).socket_id as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(socket_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nchannel as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(nchannel) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nrank as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_memseg), - "::", - stringify!(nrank) - ) - ); -} -impl Default for rte_memseg { - 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/tests/expectations/tests/issue-1554.rs b/tests/expectations/tests/issue-1554.rs deleted file mode 100644 index 7e7cddd610..0000000000 --- a/tests/expectations/tests/issue-1554.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(feature = "nightly")] -#![feature(non_exhaustive)] - -#[repr(u32)] -#[non_exhaustive] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Planet { - earth = 0, - mars = 1, -} diff --git a/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs b/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs deleted file mode 100644 index eacb34111c..0000000000 --- a/tests/expectations/tests/issue-1599-opaque-typedef-to-enum.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const a_b: a = 0; -pub const a_c: a = 1; -pub type a = ::std::os::raw::c_uint; -pub type d = u32; diff --git a/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs b/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/issue-1676-macro-namespace-prefix.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/issue-1947.rs b/tests/expectations/tests/issue-1947.rs deleted file mode 100644 index 1753ef8d02..0000000000 --- a/tests/expectations/tests/issue-1947.rs +++ /dev/null @@ -1,352 +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 const 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); - } - } -} -pub type U8 = ::std::os::raw::c_uchar; -pub type U16 = ::std::os::raw::c_ushort; -#[repr(C)] -#[repr(align(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct V56AMDY { - pub _bitfield_align_1: [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, -} -#[test] -fn bindgen_test_layout_V56AMDY() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(V56AMDY)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(V56AMDY)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).MADK as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(V56AMDY), - "::", - stringify!(MADK) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).MABR as *const _ as usize - }, - 3usize, - concat!( - "Offset of field: ", - stringify!(V56AMDY), - "::", - stringify!(MABR) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::()))._rB_ as *const _ as usize - }, - 7usize, - concat!( - "Offset of field: ", - stringify!(V56AMDY), - "::", - stringify!(_rB_) - ) - ); -} -impl V56AMDY { - #[inline] - pub fn MADZ(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 10u8) as u16) - } - } - #[inline] - pub fn set_MADZ(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 10u8, val as u64) - } - } - #[inline] - pub fn MAI0(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(10usize, 2u8) as u16) - } - } - #[inline] - pub fn set_MAI0(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(10usize, 2u8, val as u64) - } - } - #[inline] - pub fn MAI1(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(12usize, 2u8) as u16) - } - } - #[inline] - pub fn set_MAI1(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(12usize, 2u8, val as u64) - } - } - #[inline] - pub fn MAI2(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(14usize, 2u8) as u16) - } - } - #[inline] - pub fn set_MAI2(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(14usize, 2u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - MADZ: U16, - MAI0: U16, - MAI1: U16, - MAI2: U16, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 10u8, { - let MADZ: u16 = unsafe { ::std::mem::transmute(MADZ) }; - MADZ as u64 - }); - __bindgen_bitfield_unit.set(10usize, 2u8, { - let MAI0: u16 = unsafe { ::std::mem::transmute(MAI0) }; - MAI0 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 2u8, { - let MAI1: u16 = unsafe { ::std::mem::transmute(MAI1) }; - MAI1 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 2u8, { - let MAI2: u16 = unsafe { ::std::mem::transmute(MAI2) }; - MAI2 as u64 - }); - __bindgen_bitfield_unit - } - #[inline] - pub fn MATH(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(0usize, 10u8) as u16) - } - } - #[inline] - pub fn set_MATH(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_2.set(0usize, 10u8, val as u64) - } - } - #[inline] - pub fn MATE(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(10usize, 4u8) as u16) - } - } - #[inline] - pub fn set_MATE(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_2.set(10usize, 4u8, val as u64) - } - } - #[inline] - pub fn MATW(&self) -> U16 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(14usize, 2u8) as u16) - } - } - #[inline] - pub fn set_MATW(&mut self, val: U16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_2.set(14usize, 2u8, val as u64) - } - } - #[inline] - pub fn MASW(&self) -> U8 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(16usize, 4u8) as u8) - } - } - #[inline] - pub fn set_MASW(&mut self, val: U8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(16usize, 4u8, val as u64) - } - } - #[inline] - pub fn MABW(&self) -> U8 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(20usize, 3u8) as u8) - } - } - #[inline] - pub fn set_MABW(&mut self, val: U8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(20usize, 3u8, val as u64) - } - } - #[inline] - pub fn MAXN(&self) -> U8 { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(23usize, 1u8) as u8) - } - } - #[inline] - pub fn set_MAXN(&mut self, val: U8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(23usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_2( - MATH: U16, - MATE: U16, - MATW: U16, - MASW: U8, - MABW: U8, - MAXN: U8, - ) -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 10u8, { - let MATH: u16 = unsafe { ::std::mem::transmute(MATH) }; - MATH as u64 - }); - __bindgen_bitfield_unit.set(10usize, 4u8, { - let MATE: u16 = unsafe { ::std::mem::transmute(MATE) }; - MATE as u64 - }); - __bindgen_bitfield_unit.set(14usize, 2u8, { - let MATW: u16 = unsafe { ::std::mem::transmute(MATW) }; - MATW as u64 - }); - __bindgen_bitfield_unit.set(16usize, 4u8, { - let MASW: u8 = unsafe { ::std::mem::transmute(MASW) }; - MASW as u64 - }); - __bindgen_bitfield_unit.set(20usize, 3u8, { - let MABW: u8 = unsafe { ::std::mem::transmute(MABW) }; - MABW as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let MAXN: u8 = unsafe { ::std::mem::transmute(MAXN) }; - MAXN as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/issue-1977-larger-arrays.rs b/tests/expectations/tests/issue-1977-larger-arrays.rs deleted file mode 100644 index 54e5b431db..0000000000 --- a/tests/expectations/tests/issue-1977-larger-arrays.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 33usize, - concat!("Size of: ", stringify!(S)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(S)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large_array as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(S), - "::", - stringify!(large_array) - ) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct ST { - pub large_array: [T; 33usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ST { - 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/tests/expectations/tests/issue-1995.rs b/tests/expectations/tests/issue-1995.rs deleted file mode 100644 index 58e11eb297..0000000000 --- a/tests/expectations/tests/issue-1995.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This is a constant that has a docstring -/// -/// And expected to be found in generated bindings code too. -pub const FOO: ::std::os::raw::c_int = 1; -/// This is a constant that has a docstring -/// -/// And expected to be found in generated bindings code too. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(baz)) - ); -} diff --git a/tests/expectations/tests/issue-2019.rs b/tests/expectations/tests/issue-2019.rs deleted file mode 100644 index 383bd57e15..0000000000 --- a/tests/expectations/tests/issue-2019.rs +++ /dev/null @@ -1,73 +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 A { - pub a: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(a)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1A4makeEv"] - pub fn make() -> A; -} -impl A { - #[inline] - pub unsafe fn make() -> A { - make() - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct B { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(B), "::", stringify!(b)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1B4makeEv"] - pub fn make1() -> B; -} -impl B { - #[inline] - pub unsafe fn make() -> B { - make1() - } -} diff --git a/tests/expectations/tests/issue-372.rs b/tests/expectations/tests/issue-372.rs deleted file mode 100644 index 0cd9f7adb3..0000000000 --- a/tests/expectations/tests/issue-372.rs +++ /dev/null @@ -1,135 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct i { - pub j: *mut root::i, - pub k: *mut root::i, - pub l: bool, - } - #[test] - fn bindgen_test_layout_i() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(i)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(i)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).j as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(i), "::", stringify!(j)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).k as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(i), "::", stringify!(k)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).l as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(i), "::", stringify!(l)) - ); - } - impl Default for i { - 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 d { - pub m: root::i, - } - #[test] - fn bindgen_test_layout_d() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(d)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(d), "::", stringify!(m)) - ); - } - impl Default for d { - 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(u32)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub enum n { - o = 0, - p = 1, - q = 2, - r = 3, - s = 4, - t = 5, - b = 6, - ae = 7, - e = 8, - ag = 9, - ah = 10, - ai = 11, - } - #[repr(C)] - pub struct F { - pub w: [u64; 33usize], - } - #[test] - fn bindgen_test_layout_F() { - assert_eq!( - ::std::mem::size_of::(), - 264usize, - concat!("Size of: ", stringify!(F)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(F)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).w as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(F), "::", stringify!(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() - } - } - } -} diff --git a/tests/expectations/tests/issue-410.rs b/tests/expectations/tests/issue-410.rs deleted file mode 100644 index ad7463c266..0000000000 --- a/tests/expectations/tests/issue-410.rs +++ /dev/null @@ -1,49 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod JS { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Value { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Value() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Value)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Value)) - ); - } - extern "C" { - #[link_name = "\u{1}_ZN2JS5Value1aE10JSWhyMagic"] - pub fn Value_a(this: *mut root::JS::Value, arg1: root::JSWhyMagic); - } - impl Value { - #[inline] - pub unsafe fn a(&mut self, arg1: root::JSWhyMagic) { - Value_a(self, arg1) - } - } - } - #[repr(u32)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub enum JSWhyMagic { - __bindgen_cannot_repr_c_on_empty_enum = 0, - } -} diff --git a/tests/expectations/tests/issue-447.rs b/tests/expectations/tests/issue-447.rs deleted file mode 100644 index 949db73b79..0000000000 --- a/tests/expectations/tests/issue-447.rs +++ /dev/null @@ -1,76 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod mozilla { - #[allow(unused_imports)] - use self::super::super::root; - pub mod detail { - #[allow(unused_imports)] - use self::super::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct GuardObjectNotifier { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_GuardObjectNotifier() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(GuardObjectNotifier)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(GuardObjectNotifier)) - ); - } - } - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct JSAutoCompartment { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_JSAutoCompartment() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(JSAutoCompartment)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(JSAutoCompartment)) - ); - } - extern "C" { - #[link_name = "\u{1}_ZN17JSAutoCompartmentC1EN7mozilla6detail19GuardObjectNotifierE"] - pub fn JSAutoCompartment_JSAutoCompartment( - this: *mut root::JSAutoCompartment, - arg1: root::mozilla::detail::GuardObjectNotifier, - ); - } - impl JSAutoCompartment { - #[inline] - pub unsafe fn new( - arg1: root::mozilla::detail::GuardObjectNotifier, - ) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - JSAutoCompartment_JSAutoCompartment( - __bindgen_tmp.as_mut_ptr(), - arg1, - ); - __bindgen_tmp.assume_init() - } - } -} diff --git a/tests/expectations/tests/issue-493_1_0.rs b/tests/expectations/tests/issue-493_1_0.rs deleted file mode 100644 index 1a0131c327..0000000000 --- a/tests/expectations/tests/issue-493_1_0.rs +++ /dev/null @@ -1,144 +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::new() - } -} -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/tests/expectations/tests/issue-511.rs b/tests/expectations/tests/issue-511.rs deleted file mode 100644 index b7705ef2b1..0000000000 --- a/tests/expectations/tests/issue-511.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub static mut a: *mut ::std::os::raw::c_char; -} -extern "C" { - pub static mut b: *const ::std::os::raw::c_char; -} -extern "C" { - pub static c: *mut ::std::os::raw::c_char; -} -extern "C" { - pub static d: *const ::std::os::raw::c_char; -} diff --git a/tests/expectations/tests/issue-537-repr-packed-n.rs b/tests/expectations/tests/issue-537-repr-packed-n.rs deleted file mode 100644 index 13e1482d30..0000000000 --- a/tests/expectations/tests/issue-537-repr-packed-n.rs +++ /dev/null @@ -1,161 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(feature = "nightly")] - -/// This should not be opaque; we can see the attributes and can pack the -/// struct. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AlignedToOne { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_AlignedToOne() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AlignedToOne)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AlignedToOne)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AlignedToOne), - "::", - stringify!(i) - ) - ); -} -/// This should be 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AlignedToTwo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(AlignedToTwo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AlignedToTwo), - "::", - stringify!(i) - ) - ); -} -/// 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. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct PackedToOne { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_PackedToOne() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PackedToOne)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(PackedToOne)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PackedToOne), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(PackedToOne), - "::", - stringify!(y) - ) - ); -} -/// This should be be packed because Rust 1.33 has `#[repr(packed(N))]`. -#[repr(C, packed(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct PackedToTwo { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_PackedToTwo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PackedToTwo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(PackedToTwo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PackedToTwo), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(PackedToTwo), - "::", - stringify!(y) - ) - ); -} diff --git a/tests/expectations/tests/issue-537.rs b/tests/expectations/tests/issue-537.rs deleted file mode 100644 index e67c0e9c2e..0000000000 --- a/tests/expectations/tests/issue-537.rs +++ /dev/null @@ -1,163 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This should not be opaque; we can see the attributes and can pack the -/// struct. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AlignedToOne { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_AlignedToOne() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AlignedToOne)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AlignedToOne)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AlignedToOne), - "::", - stringify!(i) - ) - ); -} -/// This should be opaque because although we can see the attributes, Rust before -/// 1.33 doesn't have `#[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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(AlignedToTwo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(AlignedToTwo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AlignedToTwo), - "::", - stringify!(i) - ) - ); -} -/// 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. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct PackedToOne { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_PackedToOne() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PackedToOne)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(PackedToOne)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PackedToOne), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(PackedToOne), - "::", - stringify!(y) - ) - ); -} -/// In this case, even if we can detect the weird alignment triggered by -/// `#pragma pack(2)`, we can't do anything about it because Rust before 1.33 -/// doesn't have `#[repr(packed(N))]`. Therefore, we must make it opaque. -#[repr(C, packed(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct PackedToTwo { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_PackedToTwo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PackedToTwo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(PackedToTwo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PackedToTwo), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(PackedToTwo), - "::", - stringify!(y) - ) - ); -} diff --git a/tests/expectations/tests/issue-544-stylo-creduce-2.rs b/tests/expectations/tests/issue-544-stylo-creduce-2.rs deleted file mode 100644 index 6165419d65..0000000000 --- a/tests/expectations/tests/issue-544-stylo-creduce-2.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Foo { - pub member: Foo_SecondAlias, -} -pub type Foo_FirstAlias = [u8; 0usize]; -pub type Foo_SecondAlias = [u8; 0usize]; -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() - } - } -} diff --git a/tests/expectations/tests/issue-544-stylo-creduce.rs b/tests/expectations/tests/issue-544-stylo-creduce.rs deleted file mode 100644 index 1516c0a95e..0000000000 --- a/tests/expectations/tests/issue-544-stylo-creduce.rs +++ /dev/null @@ -1,12 +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 a { - pub _address: u8, -} diff --git a/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs b/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs deleted file mode 100644 index 997a73112d..0000000000 --- a/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const ENUM_VARIANT_1: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_1; -pub const ENUM_VARIANT_2: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_2; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - ENUM_VARIANT_1 = 0, - ENUM_VARIANT_2 = 1, -} -pub type JS_Alias = u8; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct JS_Base { - pub f: JS_Alias, -} -impl Default for JS_Base { - 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 JS_AutoIdVector { - pub _base: JS_Base, -} -#[test] -fn bindgen_test_layout_JS_AutoIdVector() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(JS_AutoIdVector)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(JS_AutoIdVector)) - ); -} -impl Default for JS_AutoIdVector { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_JS_Base_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(JS_Base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(JS_Base) - ) - ); -} diff --git a/tests/expectations/tests/issue-573-layout-test-failures.rs b/tests/expectations/tests/issue-573-layout-test-failures.rs deleted file mode 100644 index 871849aa47..0000000000 --- a/tests/expectations/tests/issue-573-layout-test-failures.rs +++ /dev/null @@ -1,55 +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 Outer { - pub i: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct AutoIdVector { - pub ar: Outer, -} -#[test] -fn bindgen_test_layout_AutoIdVector() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(AutoIdVector)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(AutoIdVector)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(AutoIdVector), - "::", - stringify!(ar) - ) - ); -} -#[test] -fn __bindgen_test_layout_Outer_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(Outer)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(Outer)) - ); -} diff --git a/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs b/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs deleted file mode 100644 index e04ff24cba..0000000000 --- a/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs +++ /dev/null @@ -1,58 +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 a { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct _bindgen_ty_1 { - pub ar: a, -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1>(), - 1usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1>(), - 1usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_bindgen_ty_1>())).ar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(ar) - ) - ); -} -extern "C" { - pub static mut AutoIdVector: _bindgen_ty_1; -} -#[test] -fn __bindgen_test_layout_a_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(a)) - ); -} diff --git a/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs b/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs deleted file mode 100644 index 01abdcc412..0000000000 --- a/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs +++ /dev/null @@ -1,121 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type RefPtr = T; - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub _address: u8, -} -pub type A_a = b; -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} -#[repr(C)] -pub struct e { - pub d: RefPtr, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for e { - 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, Default, Copy, Clone)] -pub struct f { - pub _address: u8, -} -#[repr(C)] -pub struct g { - pub h: f, -} -#[test] -fn bindgen_test_layout_g() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(g)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(g)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).h as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(g), "::", stringify!(h)) - ); -} -impl Default for g { - 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 b { - pub _base: g, -} -#[test] -fn bindgen_test_layout_b() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(b)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(b)) - ); -} -impl Default for b { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z25Servo_Element_GetSnapshotv"] - pub fn Servo_Element_GetSnapshot() -> A; -} -#[test] -fn __bindgen_test_layout_f_open0_e_open1_int_close1_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(f)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(f)) - ); -} diff --git a/tests/expectations/tests/issue-639-typedef-anon-field.rs b/tests/expectations/tests/issue-639-typedef-anon-field.rs deleted file mode 100644 index 4147c1d228..0000000000 --- a/tests/expectations/tests/issue-639-typedef-anon-field.rs +++ /dev/null @@ -1,104 +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 bar: Foo_Bar, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo_Bar { - pub abc: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Foo_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo_Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo_Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).abc as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Foo_Bar), - "::", - stringify!(abc) - ) - ); -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Baz { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Baz_Bar { - pub abc: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Baz_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Baz_Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Baz_Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).abc as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Baz_Bar), - "::", - stringify!(abc) - ) - ); -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Baz)) - ); -} diff --git a/tests/expectations/tests/issue-643-inner-struct.rs b/tests/expectations/tests/issue-643-inner-struct.rs deleted file mode 100644 index 0728500754..0000000000 --- a/tests/expectations/tests/issue-643-inner-struct.rs +++ /dev/null @@ -1,134 +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 const 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)] -#[derive(Debug)] -pub struct rte_ring { - pub memzone: *mut rte_memzone, - pub prod: rte_ring_prod, - pub cons: rte_ring_cons, - pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_ring_prod { - pub watermark: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_rte_ring_prod() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ring_prod)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ring_prod)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).watermark as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ring_prod), - "::", - stringify!(watermark) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_ring_cons { - pub sc_dequeue: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_rte_ring_cons() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ring_cons)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ring_cons)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sc_dequeue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ring_cons), - "::", - stringify!(sc_dequeue) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_ring() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_ring)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_ring)) - ); -} -impl Default for rte_ring { - 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, Default, Copy, Clone)] -pub struct rte_memzone { - pub _address: u8, -} diff --git a/tests/expectations/tests/issue-648-derive-debug-with-padding.rs b/tests/expectations/tests/issue-648-derive-debug-with-padding.rs deleted file mode 100644 index 4355486947..0000000000 --- a/tests/expectations/tests/issue-648-derive-debug-with-padding.rs +++ /dev/null @@ -1,116 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// We emit a `[u8; 63usize]` padding field for this struct, which cannot derive -/// Debug/Hash because 63 is over the hard coded limit. -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -pub struct NoDebug { - pub c: ::std::os::raw::c_char, -} -#[test] -fn bindgen_test_layout_NoDebug() { - assert_eq!( - ::std::mem::size_of::(), - 64usize, - concat!("Size of: ", stringify!(NoDebug)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(NoDebug)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NoDebug), - "::", - stringify!(c) - ) - ); -} -impl Default for NoDebug { - 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 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)] -pub struct ShouldDeriveDebugButDoesNot { - pub c: [::std::os::raw::c_char; 32usize], - pub d: ::std::os::raw::c_char, -} -#[test] -fn bindgen_test_layout_ShouldDeriveDebugButDoesNot() { - assert_eq!( - ::std::mem::size_of::(), - 64usize, - concat!("Size of: ", stringify!(ShouldDeriveDebugButDoesNot)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(ShouldDeriveDebugButDoesNot)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldDeriveDebugButDoesNot), - "::", - stringify!(c) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d - as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ShouldDeriveDebugButDoesNot), - "::", - stringify!(d) - ) - ); -} -impl Default for ShouldDeriveDebugButDoesNot { - 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 ShouldDeriveDebugButDoesNot { - fn eq(&self, other: &ShouldDeriveDebugButDoesNot) -> bool { - self.c == other.c && self.d == other.d - } -} diff --git a/tests/expectations/tests/issue-654-struct-fn-collision.rs b/tests/expectations/tests/issue-654-struct-fn-collision.rs deleted file mode 100644 index 65d3a51636..0000000000 --- a/tests/expectations/tests/issue-654-struct-fn-collision.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - _unused: [u8; 0], -} -extern "C" { - pub fn foo() -> ::std::os::raw::c_int; -} diff --git a/tests/expectations/tests/issue-674-1.rs b/tests/expectations/tests/issue-674-1.rs deleted file mode 100644 index 5ad6694730..0000000000 --- a/tests/expectations/tests/issue-674-1.rs +++ /dev/null @@ -1,53 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod mozilla { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Maybe { - pub _address: u8, - } - pub type Maybe_ValueType = T; - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct CapturingContentInfo { - pub a: u8, - } - #[test] - fn bindgen_test_layout_CapturingContentInfo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(CapturingContentInfo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(CapturingContentInfo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(CapturingContentInfo), - "::", - stringify!(a) - ) - ); - } -} diff --git a/tests/expectations/tests/issue-674-2.rs b/tests/expectations/tests/issue-674-2.rs deleted file mode 100644 index 4ccc4504c3..0000000000 --- a/tests/expectations/tests/issue-674-2.rs +++ /dev/null @@ -1,92 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod JS { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Rooted { - pub _address: u8, - } - pub type Rooted_ElementType = T; - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct c { - pub b: u8, - } - #[test] - fn bindgen_test_layout_c() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(c)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(c)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(c), "::", stringify!(b)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct B { - pub a: root::c, - } - #[test] - fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(B)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(B), "::", stringify!(a)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct StaticRefPtr { - pub _address: u8, - } - #[test] - fn __bindgen_test_layout_StaticRefPtr_open0_B_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!( - "Size of template specialization: ", - stringify!(root::StaticRefPtr) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::StaticRefPtr) - ) - ); - } -} diff --git a/tests/expectations/tests/issue-674-3.rs b/tests/expectations/tests/issue-674-3.rs deleted file mode 100644 index 99c96b969b..0000000000 --- a/tests/expectations/tests/issue-674-3.rs +++ /dev/null @@ -1,71 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct nsRefPtrHashtable { - pub _address: u8, - } - pub type nsRefPtrHashtable_UserDataType = *mut PtrType; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct a { - pub b: u8, - } - #[test] - fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(b)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct nsCSSValue { - pub c: root::a, - } - #[test] - fn bindgen_test_layout_nsCSSValue() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(nsCSSValue)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(nsCSSValue)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsCSSValue), - "::", - stringify!(c) - ) - ); - } -} diff --git a/tests/expectations/tests/issue-691-template-parameter-virtual.rs b/tests/expectations/tests/issue-691-template-parameter-virtual.rs deleted file mode 100644 index e71b2aae91..0000000000 --- a/tests/expectations/tests/issue-691-template-parameter-virtual.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct VirtualMethods__bindgen_vtable {} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VirtualMethods { - pub vtable_: *const VirtualMethods__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_VirtualMethods() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(VirtualMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(VirtualMethods)) - ); -} -impl Default for VirtualMethods { - 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, Default, Copy, Clone)] -pub struct Set { - pub bar: ::std::os::raw::c_int, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ServoElementSnapshotTable { - pub _base: Set, -} -#[test] -fn bindgen_test_layout_ServoElementSnapshotTable() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(ServoElementSnapshotTable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ServoElementSnapshotTable)) - ); -} -impl Default for ServoElementSnapshotTable { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_Set_open0_VirtualMethods_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of template specialization: ", stringify!(Set)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of template specialization: ", stringify!(Set)) - ); -} diff --git a/tests/expectations/tests/issue-710-must-use-type.rs b/tests/expectations/tests/issue-710-must-use-type.rs deleted file mode 100644 index 1d59824146..0000000000 --- a/tests/expectations/tests/issue-710-must-use-type.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, Copy, Clone)] -#[must_use] -pub struct A { - _unused: [u8; 0], -} -///
-#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[must_use] -pub struct B { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct C { - _unused: [u8; 0], -} diff --git a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs deleted file mode 100644 index 7d7b792152..0000000000 --- a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs +++ /dev/null @@ -1,194 +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 const 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)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 32usize]>, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -impl Foo { - #[inline] - pub fn m_bitfield(&self) -> ::std::os::raw::c_ulong { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 64u8) as u64) - } - } - #[inline] - pub fn set_m_bitfield(&mut self, val: ::std::os::raw::c_ulong) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_m_bar(&mut self, val: ::std::os::raw::c_ulong) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_foo(&mut self, val: ::std::os::raw::c_ulong) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bar(&mut self, val: ::std::os::raw::c_ulong) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(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, - foo: ::std::os::raw::c_ulong, - bar: ::std::os::raw::c_ulong, - ) -> __BindgenBitfieldUnit<[u8; 32usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 32usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 64u8, { - let m_bitfield: u64 = unsafe { ::std::mem::transmute(m_bitfield) }; - m_bitfield as u64 - }); - __bindgen_bitfield_unit.set(64usize, 64u8, { - let m_bar: u64 = unsafe { ::std::mem::transmute(m_bar) }; - m_bar as u64 - }); - __bindgen_bitfield_unit.set(128usize, 1u8, { - let foo: u64 = unsafe { ::std::mem::transmute(foo) }; - foo as u64 - }); - __bindgen_bitfield_unit.set(192usize, 64u8, { - let bar: u64 = unsafe { ::std::mem::transmute(bar) }; - bar as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/tests/expectations/tests/issue-801-opaque-sloppiness.rs deleted file mode 100644 index 6fe3cc681f..0000000000 --- a/tests/expectations/tests/issue-801-opaque-sloppiness.rs +++ /dev/null @@ -1,58 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct A { - _unused: [u8; 0], -} -#[repr(C)] -#[repr(align(1))] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct B { - pub _bindgen_opaque_blob: u8, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(B)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN1B1aE"] - pub static mut B_a: A; -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct C { - pub b: B, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(b)) - ); -} diff --git a/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs b/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs deleted file mode 100644 index 7fd9caa309..0000000000 --- a/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs +++ /dev/null @@ -1,135 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Pupper { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Pupper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Pupper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Pupper)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Doggo { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Doggo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Doggo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Doggo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct SuchWow { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_SuchWow() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(SuchWow)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(SuchWow)) - ); -} -#[repr(C)] -#[repr(align(1))] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Opaque { - pub _bindgen_opaque_blob: u8, -} -#[test] -fn bindgen_test_layout_Opaque() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Opaque)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Opaque)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN6Opaque17eleven_out_of_tenEv"] - pub fn Opaque_eleven_out_of_ten(this: *mut Opaque) -> SuchWow; -} -extern "C" { - #[link_name = "\u{1}_ZN6OpaqueC1E6Pupper"] - pub fn Opaque_Opaque(this: *mut Opaque, pup: Pupper); -} -impl Opaque { - #[inline] - pub unsafe fn eleven_out_of_ten(&mut self) -> SuchWow { - Opaque_eleven_out_of_ten(self) - } - #[inline] - pub unsafe fn new(pup: Pupper) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Opaque_Opaque(__bindgen_tmp.as_mut_ptr(), pup); - __bindgen_tmp.assume_init() - } -} -extern "C" { - #[link_name = "\u{1}_ZN6Opaque11MAJESTIC_AFE"] - pub static mut Opaque_MAJESTIC_AF: Doggo; -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Allowlisted { - pub some_member: Opaque, -} -#[test] -fn bindgen_test_layout_Allowlisted() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Allowlisted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Allowlisted)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).some_member as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Allowlisted), - "::", - stringify!(some_member) - ) - ); -} diff --git a/tests/expectations/tests/issue-816.rs b/tests/expectations/tests/issue-816.rs deleted file mode 100644 index c7f94106f4..0000000000 --- a/tests/expectations/tests/issue-816.rs +++ /dev/null @@ -1,860 +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 const 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)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct capabilities { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, -} -#[test] -fn bindgen_test_layout_capabilities() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(capabilities)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(capabilities)) - ); -} -impl capabilities { - #[inline] - pub fn bit_1(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) - } - } - #[inline] - pub fn set_bit_1(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_2(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_3(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_4(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_5(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_6(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_7(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_8(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_9(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_10(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_11(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_12(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_13(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_14(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_15(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_16(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_17(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_18(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_19(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_20(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_21(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_22(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_23(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_24(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_25(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_26(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_27(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_28(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_29(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_30(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_31(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_32(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_33(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_34(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_35(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_36(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_37(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_38(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_39(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_40(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_bit_41(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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, - bit_3: ::std::os::raw::c_uint, - bit_4: ::std::os::raw::c_uint, - bit_5: ::std::os::raw::c_uint, - bit_6: ::std::os::raw::c_uint, - bit_7: ::std::os::raw::c_uint, - bit_8: ::std::os::raw::c_uint, - bit_9: ::std::os::raw::c_uint, - bit_10: ::std::os::raw::c_uint, - bit_11: ::std::os::raw::c_uint, - bit_12: ::std::os::raw::c_uint, - bit_13: ::std::os::raw::c_uint, - bit_14: ::std::os::raw::c_uint, - bit_15: ::std::os::raw::c_uint, - bit_16: ::std::os::raw::c_uint, - bit_17: ::std::os::raw::c_uint, - bit_18: ::std::os::raw::c_uint, - bit_19: ::std::os::raw::c_uint, - bit_20: ::std::os::raw::c_uint, - bit_21: ::std::os::raw::c_uint, - bit_22: ::std::os::raw::c_uint, - bit_23: ::std::os::raw::c_uint, - bit_24: ::std::os::raw::c_uint, - bit_25: ::std::os::raw::c_uint, - bit_26: ::std::os::raw::c_uint, - bit_27: ::std::os::raw::c_uint, - bit_28: ::std::os::raw::c_uint, - bit_29: ::std::os::raw::c_uint, - bit_30: ::std::os::raw::c_uint, - bit_31: ::std::os::raw::c_uint, - bit_32: ::std::os::raw::c_uint, - bit_33: ::std::os::raw::c_uint, - bit_34: ::std::os::raw::c_uint, - bit_35: ::std::os::raw::c_uint, - bit_36: ::std::os::raw::c_uint, - bit_37: ::std::os::raw::c_uint, - bit_38: ::std::os::raw::c_uint, - bit_39: ::std::os::raw::c_uint, - bit_40: ::std::os::raw::c_uint, - bit_41: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 16usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let bit_1: u32 = unsafe { ::std::mem::transmute(bit_1) }; - bit_1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let bit_2: u32 = unsafe { ::std::mem::transmute(bit_2) }; - bit_2 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let bit_3: u32 = unsafe { ::std::mem::transmute(bit_3) }; - bit_3 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let bit_4: u32 = unsafe { ::std::mem::transmute(bit_4) }; - bit_4 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let bit_5: u32 = unsafe { ::std::mem::transmute(bit_5) }; - bit_5 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let bit_6: u32 = unsafe { ::std::mem::transmute(bit_6) }; - bit_6 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let bit_7: u32 = unsafe { ::std::mem::transmute(bit_7) }; - bit_7 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let bit_8: u32 = unsafe { ::std::mem::transmute(bit_8) }; - bit_8 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let bit_9: u32 = unsafe { ::std::mem::transmute(bit_9) }; - bit_9 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let bit_10: u32 = unsafe { ::std::mem::transmute(bit_10) }; - bit_10 as u64 - }); - __bindgen_bitfield_unit.set(10usize, 1u8, { - let bit_11: u32 = unsafe { ::std::mem::transmute(bit_11) }; - bit_11 as u64 - }); - __bindgen_bitfield_unit.set(11usize, 1u8, { - let bit_12: u32 = unsafe { ::std::mem::transmute(bit_12) }; - bit_12 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 1u8, { - let bit_13: u32 = unsafe { ::std::mem::transmute(bit_13) }; - bit_13 as u64 - }); - __bindgen_bitfield_unit.set(13usize, 1u8, { - let bit_14: u32 = unsafe { ::std::mem::transmute(bit_14) }; - bit_14 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 1u8, { - let bit_15: u32 = unsafe { ::std::mem::transmute(bit_15) }; - bit_15 as u64 - }); - __bindgen_bitfield_unit.set(15usize, 1u8, { - let bit_16: u32 = unsafe { ::std::mem::transmute(bit_16) }; - bit_16 as u64 - }); - __bindgen_bitfield_unit.set(16usize, 1u8, { - let bit_17: u32 = unsafe { ::std::mem::transmute(bit_17) }; - bit_17 as u64 - }); - __bindgen_bitfield_unit.set(17usize, 1u8, { - let bit_18: u32 = unsafe { ::std::mem::transmute(bit_18) }; - bit_18 as u64 - }); - __bindgen_bitfield_unit.set(18usize, 1u8, { - let bit_19: u32 = unsafe { ::std::mem::transmute(bit_19) }; - bit_19 as u64 - }); - __bindgen_bitfield_unit.set(19usize, 1u8, { - let bit_20: u32 = unsafe { ::std::mem::transmute(bit_20) }; - bit_20 as u64 - }); - __bindgen_bitfield_unit.set(20usize, 1u8, { - let bit_21: u32 = unsafe { ::std::mem::transmute(bit_21) }; - bit_21 as u64 - }); - __bindgen_bitfield_unit.set(21usize, 1u8, { - let bit_22: u32 = unsafe { ::std::mem::transmute(bit_22) }; - bit_22 as u64 - }); - __bindgen_bitfield_unit.set(22usize, 1u8, { - let bit_23: u32 = unsafe { ::std::mem::transmute(bit_23) }; - bit_23 as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let bit_24: u32 = unsafe { ::std::mem::transmute(bit_24) }; - bit_24 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 1u8, { - let bit_25: u32 = unsafe { ::std::mem::transmute(bit_25) }; - bit_25 as u64 - }); - __bindgen_bitfield_unit.set(25usize, 1u8, { - let bit_26: u32 = unsafe { ::std::mem::transmute(bit_26) }; - bit_26 as u64 - }); - __bindgen_bitfield_unit.set(26usize, 1u8, { - let bit_27: u32 = unsafe { ::std::mem::transmute(bit_27) }; - bit_27 as u64 - }); - __bindgen_bitfield_unit.set(27usize, 1u8, { - let bit_28: u32 = unsafe { ::std::mem::transmute(bit_28) }; - bit_28 as u64 - }); - __bindgen_bitfield_unit.set(28usize, 1u8, { - let bit_29: u32 = unsafe { ::std::mem::transmute(bit_29) }; - bit_29 as u64 - }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let bit_30: u32 = unsafe { ::std::mem::transmute(bit_30) }; - bit_30 as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let bit_31: u32 = unsafe { ::std::mem::transmute(bit_31) }; - bit_31 as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let bit_32: u32 = unsafe { ::std::mem::transmute(bit_32) }; - bit_32 as u64 - }); - __bindgen_bitfield_unit.set(32usize, 1u8, { - let bit_33: u32 = unsafe { ::std::mem::transmute(bit_33) }; - bit_33 as u64 - }); - __bindgen_bitfield_unit.set(33usize, 1u8, { - let bit_34: u32 = unsafe { ::std::mem::transmute(bit_34) }; - bit_34 as u64 - }); - __bindgen_bitfield_unit.set(34usize, 1u8, { - let bit_35: u32 = unsafe { ::std::mem::transmute(bit_35) }; - bit_35 as u64 - }); - __bindgen_bitfield_unit.set(35usize, 1u8, { - let bit_36: u32 = unsafe { ::std::mem::transmute(bit_36) }; - bit_36 as u64 - }); - __bindgen_bitfield_unit.set(36usize, 1u8, { - let bit_37: u32 = unsafe { ::std::mem::transmute(bit_37) }; - bit_37 as u64 - }); - __bindgen_bitfield_unit.set(37usize, 1u8, { - let bit_38: u32 = unsafe { ::std::mem::transmute(bit_38) }; - bit_38 as u64 - }); - __bindgen_bitfield_unit.set(38usize, 1u8, { - let bit_39: u32 = unsafe { ::std::mem::transmute(bit_39) }; - bit_39 as u64 - }); - __bindgen_bitfield_unit.set(39usize, 1u8, { - let bit_40: u32 = unsafe { ::std::mem::transmute(bit_40) }; - bit_40 as u64 - }); - __bindgen_bitfield_unit.set(40usize, 1u8, { - let bit_41: u32 = unsafe { ::std::mem::transmute(bit_41) }; - bit_41 as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs b/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs deleted file mode 100644 index cfe0078455..0000000000 --- a/tests/expectations/tests/issue-820-unused-template-param-in-alias.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Foo_self_type = u8; diff --git a/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.rs b/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.rs deleted file mode 100644 index f5ba025a25..0000000000 --- a/tests/expectations/tests/issue-826-generating-methods-when-asked-not-to.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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/issue-833-1.rs b/tests/expectations/tests/issue-833-1.rs deleted file mode 100644 index f91266f634..0000000000 --- a/tests/expectations/tests/issue-833-1.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct nsTArray { - pub hdr: *const (), -} - -extern "C" { - pub fn func() -> *mut nsTArray; -} diff --git a/tests/expectations/tests/issue-833-2.rs b/tests/expectations/tests/issue-833-2.rs deleted file mode 100644 index 1dfe1abda6..0000000000 --- a/tests/expectations/tests/issue-833-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -// If the output of this changes, please ensure issue-833-1.hpp changes too - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct nsTArray { - pub _address: u8, -} diff --git a/tests/expectations/tests/issue-833.rs b/tests/expectations/tests/issue-833.rs deleted file mode 100644 index a092fb7156..0000000000 --- a/tests/expectations/tests/issue-833.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct nsTArray { - pub hdr: *const T, -} - -extern "C" { - pub fn func() -> *mut nsTArray<::std::os::raw::c_int>; -} diff --git a/tests/expectations/tests/issue-834.rs b/tests/expectations/tests/issue-834.rs deleted file mode 100644 index 465341fb71..0000000000 --- a/tests/expectations/tests/issue-834.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 U { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_U() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(U)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(U)) - ); -} diff --git a/tests/expectations/tests/issue-848-replacement-system-include.rs b/tests/expectations/tests/issue-848-replacement-system-include.rs deleted file mode 100644 index 294df575da..0000000000 --- a/tests/expectations/tests/issue-848-replacement-system-include.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This is intended to replace another type, but won't if we treat this include -/// as a system include, because clang doesn't parse comments there. -/// -/// See #848. -/// -///
-#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct nsTArray { - pub m: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for nsTArray { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - pub fn func() -> *mut nsTArray<::std::os::raw::c_int>; -} diff --git a/tests/expectations/tests/issue-888-enum-var-decl-jump.rs b/tests/expectations/tests/issue-888-enum-var-decl-jump.rs deleted file mode 100644 index 6ac308a74f..0000000000 --- a/tests/expectations/tests/issue-888-enum-var-decl-jump.rs +++ /dev/null @@ -1,43 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod Halide { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Type { - pub _address: u8, - } - extern "C" { - #[link_name = "\u{1}_ZN6Halide4Type1bE"] - pub static mut Type_b: root::a; - } - #[test] - fn bindgen_test_layout_Type() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Type)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Type)) - ); - } - } - #[repr(u32)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub enum a { - __bindgen_cannot_repr_c_on_empty_enum = 0, - } -} diff --git a/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs b/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs deleted file mode 100644 index dc50fe1bfa..0000000000 --- a/tests/expectations/tests/issue-944-derive-copy-and-blocklisting.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub struct BlocklistMe(u8); - -/// Because this type contains a blocklisted type, it should not derive Copy. -#[repr(C)] -pub struct ShouldNotBeCopy { - pub a: BlocklistMe, -} -#[test] -fn bindgen_test_layout_ShouldNotBeCopy() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ShouldNotBeCopy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ShouldNotBeCopy)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ShouldNotBeCopy), - "::", - stringify!(a) - ) - ); -} -impl Default for ShouldNotBeCopy { - 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/tests/expectations/tests/issue-946.rs b/tests/expectations/tests/issue-946.rs deleted file mode 100644 index 897700b325..0000000000 --- a/tests/expectations/tests/issue-946.rs +++ /dev/null @@ -1,24 +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 {} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(foo)) - ); -} -pub type bar = foo; diff --git a/tests/expectations/tests/issue_311.rs b/tests/expectations/tests/issue_311.rs deleted file mode 100644 index 49e30d8407..0000000000 --- a/tests/expectations/tests/issue_311.rs +++ /dev/null @@ -1,48 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct jsval_layout { - pub __bindgen_anon_1: root::jsval_layout__bindgen_ty_1, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct jsval_layout__bindgen_ty_1 { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_jsval_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(jsval_layout__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(jsval_layout__bindgen_ty_1)) - ); - } - #[test] - fn bindgen_test_layout_jsval_layout() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(jsval_layout)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(jsval_layout)) - ); - } -} diff --git a/tests/expectations/tests/issue_315.rs b/tests/expectations/tests/issue_315.rs deleted file mode 100644 index 71ae1f2746..0000000000 --- a/tests/expectations/tests/issue_315.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-pub type c
= a; diff --git a/tests/expectations/tests/jsval_layout_opaque.rs b/tests/expectations/tests/jsval_layout_opaque.rs deleted file mode 100644 index 5b8427913c..0000000000 --- a/tests/expectations/tests/jsval_layout_opaque.rs +++ /dev/null @@ -1,525 +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 const 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); - } - } -} -pub const JSVAL_TAG_SHIFT: u32 = 47; -pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; -pub const JSVAL_TAG_MASK: i64 = -140737488355328; -pub type size_t = ::std::os::raw::c_ulonglong; -#[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(Copy, Clone)] -pub union jsval_layout { - pub asBits: u64, - pub debugView: jsval_layout__bindgen_ty_1, - pub s: jsval_layout__bindgen_ty_2, - pub asDouble: f64, - pub asPtr: *mut ::std::os::raw::c_void, - pub asWord: size_t, - pub asUIntPtr: usize, -} -#[repr(C)] -#[repr(align(8))] -#[derive(Debug, Copy, Clone, 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, - concat!("Size of: ", stringify!(jsval_layout__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(jsval_layout__bindgen_ty_1)) - ); -} -impl Default for jsval_layout__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 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(Copy, Clone)] -pub struct jsval_layout__bindgen_ty_2 { - pub payload: jsval_layout__bindgen_ty_2__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union jsval_layout__bindgen_ty_2__bindgen_ty_1 { - pub i32_: i32, - pub u32_: u32, - pub why: JSWhyMagic, -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_2__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .i32_ as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(i32_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .u32_ as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(u32_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .why as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(why) - ) - ); -} -impl Default for jsval_layout__bindgen_ty_2__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() - } - } -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(jsval_layout__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(jsval_layout__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).payload - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2), - "::", - stringify!(payload) - ) - ); -} -impl Default for jsval_layout__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_jsval_layout() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(jsval_layout)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(jsval_layout)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asBits as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asBits) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).debugView as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(debugView) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).s as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(s) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asDouble as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asDouble) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asPtr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asPtr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asWord as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asWord) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asUIntPtr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asUIntPtr) - ) - ); -} -impl Default for jsval_layout { - 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(Copy, Clone)] -pub struct Value { - pub data: jsval_layout, -} -#[test] -fn bindgen_test_layout_Value() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Value)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Value)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Value), - "::", - stringify!(data) - ) - ); -} -impl Default for Value { - 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/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/tests/expectations/tests/jsval_layout_opaque_1_0.rs deleted file mode 100644 index 260282dbba..0000000000 --- a/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ /dev/null @@ -1,559 +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::new() - } -} -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; -pub type size_t = ::std::os::raw::c_ulonglong; -#[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]>, - pub __bindgen_align: [u64; 0usize], -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(jsval_layout__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .i32_ as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(i32_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .u32_ as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(u32_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .why as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(jsval_layout__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(jsval_layout__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).payload - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout__bindgen_ty_2), - "::", - stringify!(payload) - ) - ); -} -impl Clone for jsval_layout__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_jsval_layout() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(jsval_layout)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(jsval_layout)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asBits as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asBits) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).debugView as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(debugView) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).s as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(s) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asDouble as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asDouble) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asPtr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asPtr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asWord as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(asWord) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).asUIntPtr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(jsval_layout), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Value)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Value)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Value), - "::", - stringify!(data) - ) - ); -} -impl Clone for Value { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/layout.rs b/tests/expectations/tests/layout.rs deleted file mode 100644 index ae417259cd..0000000000 --- a/tests/expectations/tests/layout.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![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, - concat!("Size of: ", stringify!(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 - } - } -} diff --git a/tests/expectations/tests/layout_align.rs b/tests/expectations/tests/layout_align.rs deleted file mode 100644 index cb34df3e76..0000000000 --- a/tests/expectations/tests/layout_align.rs +++ /dev/null @@ -1,261 +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 const 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)] -#[derive(Default)] -pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); -impl __IncompleteArrayField { - #[inline] - pub const 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)] -#[derive(Debug)] -pub struct rte_kni_fifo { - ///< Next position to be written - pub write: ::std::os::raw::c_uint, - ///< Next position to be read - pub read: ::std::os::raw::c_uint, - ///< Circular buffer length - pub len: ::std::os::raw::c_uint, - ///< Pointer size - for 32/64 bit OS - pub elem_size: ::std::os::raw::c_uint, - ///< The buffer contains mbuf pointers - pub buffer: __IncompleteArrayField<*mut ::std::os::raw::c_void>, -} -#[test] -fn bindgen_test_layout_rte_kni_fifo() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_kni_fifo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_kni_fifo)) - ); -} -impl Default for rte_kni_fifo { - 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)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_eth_link { - ///< 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], -} -#[test] -fn bindgen_test_layout_rte_eth_link() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_eth_link)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_link)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).link_speed as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_link), - "::", - stringify!(link_speed) - ) - ); -} -impl rte_eth_link { - #[inline] - pub fn link_duplex(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_duplex(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn link_autoneg(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_autoneg(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(1usize, 1u8, val as u64) - } - } - #[inline] - pub fn link_status(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_status(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(2usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - link_duplex: u16, - link_autoneg: u16, - link_status: u16, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let link_duplex: u16 = - unsafe { ::std::mem::transmute(link_duplex) }; - link_duplex as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let link_autoneg: u16 = - unsafe { ::std::mem::transmute(link_autoneg) }; - link_autoneg as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let link_status: u16 = - unsafe { ::std::mem::transmute(link_status) }; - link_status as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/layout_arp.rs b/tests/expectations/tests/layout_arp.rs deleted file mode 100644 index d6642d7e2b..0000000000 --- a/tests/expectations/tests/layout_arp.rs +++ /dev/null @@ -1,226 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const ETHER_ADDR_LEN: u32 = 6; -pub const ARP_HRD_ETHER: u32 = 1; -pub const ARP_OP_REQUEST: u32 = 1; -pub const ARP_OP_REPLY: u32 = 2; -pub const ARP_OP_REVREQUEST: u32 = 3; -pub const ARP_OP_REVREPLY: u32 = 4; -pub const ARP_OP_INVREQUEST: u32 = 8; -pub const ARP_OP_INVREPLY: u32 = 9; -/// Ethernet address: -/// A universally administered address is uniquely assigned to a device by its -/// manufacturer. The first three octets (in transmission order) contain the -/// Organizationally Unique Identifier (OUI). The following three (MAC-48 and -/// EUI-48) octets are assigned by that organization with the only constraint -/// of uniqueness. -/// A locally administered address is assigned to a device by a network -/// administrator and does not contain OUIs. -/// See http://standards.ieee.org/regauth/groupmac/tutorial.html -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ether_addr { - ///< Addr bytes in tx order - pub addr_bytes: [u8; 6usize], -} -#[test] -fn bindgen_test_layout_ether_addr() { - assert_eq!( - ::std::mem::size_of::(), - 6usize, - concat!("Size of: ", stringify!(ether_addr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ether_addr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).addr_bytes as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ether_addr), - "::", - stringify!(addr_bytes) - ) - ); -} -/// ARP header IPv4 payload. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct arp_ipv4 { - ///< sender hardware address - pub arp_sha: ether_addr, - ///< sender IP address - pub arp_sip: u32, - ///< target hardware address - pub arp_tha: ether_addr, - ///< target IP address - pub arp_tip: u32, -} -#[test] -fn bindgen_test_layout_arp_ipv4() { - assert_eq!( - ::std::mem::size_of::(), - 20usize, - concat!("Size of: ", stringify!(arp_ipv4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(arp_ipv4)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_sha as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(arp_ipv4), - "::", - stringify!(arp_sha) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_sip as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(arp_ipv4), - "::", - stringify!(arp_sip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_tha as *const _ as usize - }, - 10usize, - concat!( - "Offset of field: ", - stringify!(arp_ipv4), - "::", - stringify!(arp_tha) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_tip as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(arp_ipv4), - "::", - stringify!(arp_tip) - ) - ); -} -/// ARP header. -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct arp_hdr { - pub arp_hrd: u16, - pub arp_pro: u16, - pub arp_hln: u8, - pub arp_pln: u8, - pub arp_op: u16, - pub arp_data: arp_ipv4, -} -#[test] -fn bindgen_test_layout_arp_hdr() { - assert_eq!( - ::std::mem::size_of::(), - 28usize, - concat!("Size of: ", stringify!(arp_hdr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(arp_hdr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_hrd as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_hrd) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_pro as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_pro) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_hln as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_hln) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_pln as *const _ as usize - }, - 5usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_pln) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_op as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_op) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arp_data as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(arp_hdr), - "::", - stringify!(arp_data) - ) - ); -} diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs deleted file mode 100644 index 3ba1b6d0ba..0000000000 --- a/tests/expectations/tests/layout_array.rs +++ /dev/null @@ -1,428 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -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; -pub const RTE_HEAP_NUM_FREELISTS: u32 = 13; -pub type size_t = ::std::os::raw::c_longlong; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct rte_mempool { - _unused: [u8; 0], -} -/// Prototype for implementation specific data provisioning function. -/// -/// The function should provide the implementation specific memory for -/// for use by the other mempool ops functions in a given mempool ops struct. -/// E.g. the default ops provides an instance of the rte_ring for this purpose. -/// it will most likely point to a different type of data structure, and -/// will be transparent to the application programmer. -/// This function should set mp->pool_data. -pub type rte_mempool_alloc_t = ::std::option::Option< - unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int, ->; -/// Free the opaque private data pointed to by mp->pool_data pointer. -pub type rte_mempool_free_t = - ::std::option::Option; -/// Enqueue an object into the external pool. -pub type rte_mempool_enqueue_t = ::std::option::Option< - unsafe extern "C" fn( - mp: *mut rte_mempool, - obj_table: *const *mut ::std::os::raw::c_void, - n: ::std::os::raw::c_uint, - ) -> ::std::os::raw::c_int, ->; -/// Dequeue an object from the external pool. -pub type rte_mempool_dequeue_t = ::std::option::Option< - unsafe extern "C" fn( - mp: *mut rte_mempool, - obj_table: *mut *mut ::std::os::raw::c_void, - n: ::std::os::raw::c_uint, - ) -> ::std::os::raw::c_int, ->; -/// Return the number of available objects in the external pool. -pub type rte_mempool_get_count = ::std::option::Option< - unsafe extern "C" fn(mp: *const rte_mempool) -> ::std::os::raw::c_uint, ->; -/// Structure defining mempool operations structure -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -pub struct rte_mempool_ops { - ///< Name of mempool ops struct. - pub name: [::std::os::raw::c_char; 32usize], - ///< Allocate private data. - pub alloc: rte_mempool_alloc_t, - ///< Free the external pool. - pub free: rte_mempool_free_t, - ///< Enqueue an object. - pub enqueue: rte_mempool_enqueue_t, - ///< Dequeue an object. - pub dequeue: rte_mempool_dequeue_t, - ///< Get qty of available objs. - pub get_count: rte_mempool_get_count, -} -#[test] -fn bindgen_test_layout_rte_mempool_ops() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(rte_mempool_ops)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_mempool_ops)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).name as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).alloc as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(alloc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).free as *const _ - as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(free) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).enqueue as *const _ - as usize - }, - 48usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(enqueue) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dequeue as *const _ - as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(dequeue) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get_count as *const _ - as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops), - "::", - stringify!(get_count) - ) - ); -} -impl Default for rte_mempool_ops { - 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 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)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_spinlock_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_spinlock_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).locked as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_spinlock_t), - "::", - stringify!(locked) - ) - ); -} -/// 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 -/// the mempools can be shared across primary and secondary processes. -/// The indices used to access the array are valid across processes, whereas -/// any function pointers stored directly in the mempool struct would not be. -/// This results in us simply having "ops_index" in the mempool struct. -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -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], - /// Storage for all possible ops structs. - pub ops: [rte_mempool_ops; 16usize], -} -#[test] -fn bindgen_test_layout_rte_mempool_ops_table() { - assert_eq!( - ::std::mem::size_of::(), - 2112usize, - concat!("Size of: ", stringify!(rte_mempool_ops_table)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_mempool_ops_table)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sl as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops_table), - "::", - stringify!(sl) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).num_ops - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops_table), - "::", - stringify!(num_ops) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ops as *const _ - as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_mempool_ops_table), - "::", - stringify!(ops) - ) - ); -} -impl Default for rte_mempool_ops_table { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// Structure to hold malloc heap -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -pub struct malloc_heap { - pub lock: rte_spinlock_t, - pub free_head: [malloc_heap__bindgen_ty_1; 13usize], - pub alloc_count: ::std::os::raw::c_uint, - pub total_size: size_t, -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct malloc_heap__bindgen_ty_1 { - pub lh_first: *mut malloc_elem, -} -#[test] -fn bindgen_test_layout_malloc_heap__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(malloc_heap__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(malloc_heap__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lh_first - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(malloc_heap__bindgen_ty_1), - "::", - stringify!(lh_first) - ) - ); -} -impl Default for malloc_heap__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() - } - } -} -#[test] -fn bindgen_test_layout_malloc_heap() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(malloc_heap)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(malloc_heap)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lock as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(malloc_heap), - "::", - stringify!(lock) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).free_head as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(malloc_heap), - "::", - stringify!(free_head) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).alloc_count as *const _ - as usize - }, - 112usize, - concat!( - "Offset of field: ", - stringify!(malloc_heap), - "::", - stringify!(alloc_count) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).total_size as *const _ - as usize - }, - 120usize, - concat!( - "Offset of field: ", - stringify!(malloc_heap), - "::", - stringify!(total_size) - ) - ); -} -impl Default for malloc_heap { - 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 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 { - pub _address: u8, -} diff --git a/tests/expectations/tests/layout_array_too_long.rs b/tests/expectations/tests/layout_array_too_long.rs deleted file mode 100644 index c9880ea2a9..0000000000 --- a/tests/expectations/tests/layout_array_too_long.rs +++ /dev/null @@ -1,348 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const RTE_CACHE_LINE_SIZE: u32 = 64; -pub const RTE_LIBRTE_IP_FRAG_MAX_FRAG: u32 = 4; -pub const IP_LAST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_LAST_FRAG_IDX; -pub const IP_FIRST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_FIRST_FRAG_IDX; -pub const IP_MIN_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MIN_FRAG_NUM; -pub const IP_MAX_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MAX_FRAG_NUM; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - ///< index of last fragment - IP_LAST_FRAG_IDX = 0, - ///< index of first fragment - IP_FIRST_FRAG_IDX = 1, - ///< minimum number of fragments - IP_MIN_FRAG_NUM = 2, - IP_MAX_FRAG_NUM = 4, -} -/// @internal fragmented mbuf -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ip_frag { - ///< offset into the packet - pub ofs: u16, - ///< length of fragment - pub len: u16, - ///< fragment mbuf - pub mb: *mut rte_mbuf, -} -#[test] -fn bindgen_test_layout_ip_frag() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ip_frag)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ofs as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(ofs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, - 2usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mb as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(mb) - ) - ); -} -impl Default for ip_frag { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// @internal to uniquely indetify fragmented datagram. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ip_frag_key { - ///< src address, first 8 bytes used for IPv4 - pub src_dst: [u64; 4usize], - ///< dst address - pub id: u32, - ///< src/dst key length - pub key_len: u32, -} -#[test] -fn bindgen_test_layout_ip_frag_key() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ip_frag_key)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag_key)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_dst as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(src_dst) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).id as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).key_len as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(key_len) - ) - ); -} -/// @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)] -pub struct ip_frag_pkt { - ///< LRU list - pub lru: ip_frag_pkt__bindgen_ty_1, - ///< fragmentation key - pub key: ip_frag_key, - ///< creation timestamp - pub start: u64, - ///< expected reassembled size - pub total_size: u32, - ///< size of fragments received - pub frag_size: u32, - ///< index of next entry to fill - pub last_idx: u32, - ///< fragments - pub frags: [ip_frag; 4usize], -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ip_frag_pkt__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag_pkt__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqe_next - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt__bindgen_ty_1), - "::", - stringify!(tqe_next) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqe_prev - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt__bindgen_ty_1), - "::", - stringify!(tqe_prev) - ) - ); -} -impl Default for ip_frag_pkt__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() - } - } -} -#[test] -fn bindgen_test_layout_ip_frag_pkt() { - assert_eq!( - ::std::mem::size_of::(), - 192usize, - concat!("Size of: ", stringify!(ip_frag_pkt)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(ip_frag_pkt)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lru as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(lru) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).key as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(key) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).start as *const _ as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(start) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).total_size as *const _ - as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(total_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).frag_size as *const _ - as usize - }, - 68usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(frag_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).last_idx as *const _ - as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(last_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).frags as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(frags) - ) - ); -} -impl Default for ip_frag_pkt { - 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 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)] -pub struct rte_mbuf { - pub _address: u8, -} diff --git a/tests/expectations/tests/layout_cmdline_token.rs b/tests/expectations/tests/layout_cmdline_token.rs deleted file mode 100644 index 47170dd709..0000000000 --- a/tests/expectations/tests/layout_cmdline_token.rs +++ /dev/null @@ -1,291 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// Stores a pointer to the ops struct, and the offset: the place to -/// write the parsed result in the destination structure. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct cmdline_token_hdr { - pub ops: *mut cmdline_token_ops, - pub offset: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_cmdline_token_hdr() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(cmdline_token_hdr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(cmdline_token_hdr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ops as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_hdr), - "::", - stringify!(ops) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).offset as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_hdr), - "::", - stringify!(offset) - ) - ); -} -impl Default for cmdline_token_hdr { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// Stores a pointer to the ops struct, and the offset: the place to -/// write the parsed result in the destination structure. -pub type cmdline_parse_token_hdr_t = cmdline_token_hdr; -/// A token is defined by this structure. -/// -/// parse() takes the token as first argument, then the source buffer -/// starting at the token we want to parse. The 3rd arg is a pointer -/// where we store the parsed data (as binary). It returns the number of -/// parsed chars on success and a negative value on error. -/// -/// complete_get_nb() returns the number of possible values for this -/// token if completion is possible. If it is NULL or if it returns 0, -/// no completion is possible. -/// -/// complete_get_elt() copy in dstbuf (the size is specified in the -/// parameter) the i-th possible completion for this token. returns 0 -/// on success or and a negative value on error. -/// -/// get_help() fills the dstbuf with the help for the token. It returns -/// -1 on error and 0 on success. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct cmdline_token_ops { - /// parse(token ptr, buf, res pts, buf len) - pub parse: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut cmdline_parse_token_hdr_t, - arg2: *const ::std::os::raw::c_char, - arg3: *mut ::std::os::raw::c_void, - arg4: ::std::os::raw::c_uint, - ) -> ::std::os::raw::c_int, - >, - /// return the num of possible choices for this token - pub complete_get_nb: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut cmdline_parse_token_hdr_t, - ) -> ::std::os::raw::c_int, - >, - /// return the elt x for this token (token, idx, dstbuf, size) - pub complete_get_elt: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut cmdline_parse_token_hdr_t, - arg2: ::std::os::raw::c_int, - arg3: *mut ::std::os::raw::c_char, - arg4: ::std::os::raw::c_uint, - ) -> ::std::os::raw::c_int, - >, - /// get help for this token (token, dstbuf, size) - pub get_help: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut cmdline_parse_token_hdr_t, - arg2: *mut ::std::os::raw::c_char, - arg3: ::std::os::raw::c_uint, - ) -> ::std::os::raw::c_int, - >, -} -#[test] -fn bindgen_test_layout_cmdline_token_ops() { - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(cmdline_token_ops)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(cmdline_token_ops)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).parse as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_ops), - "::", - stringify!(parse) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).complete_get_nb - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_ops), - "::", - stringify!(complete_get_nb) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).complete_get_elt - as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_ops), - "::", - stringify!(complete_get_elt) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get_help as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_ops), - "::", - stringify!(get_help) - ) - ); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum cmdline_numtype { - UINT8 = 0, - UINT16 = 1, - UINT32 = 2, - UINT64 = 3, - INT8 = 4, - INT16 = 5, - INT32 = 6, - INT64 = 7, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct cmdline_token_num_data { - pub type_: cmdline_numtype, -} -#[test] -fn bindgen_test_layout_cmdline_token_num_data() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(cmdline_token_num_data)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(cmdline_token_num_data)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).type_ as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_num_data), - "::", - stringify!(type_) - ) - ); -} -impl Default for cmdline_token_num_data { - 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 cmdline_token_num { - pub hdr: cmdline_token_hdr, - pub num_data: cmdline_token_num_data, -} -#[test] -fn bindgen_test_layout_cmdline_token_num() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(cmdline_token_num)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(cmdline_token_num)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hdr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_num), - "::", - stringify!(hdr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).num_data as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cmdline_token_num), - "::", - stringify!(num_data) - ) - ); -} -impl Default for cmdline_token_num { - 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 type cmdline_parse_token_num_t = cmdline_token_num; diff --git a/tests/expectations/tests/layout_eth_conf.rs b/tests/expectations/tests/layout_eth_conf.rs deleted file mode 100644 index e880608203..0000000000 --- a/tests/expectations/tests/layout_eth_conf.rs +++ /dev/null @@ -1,2264 +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 const 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); - } - } -} -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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_rxmode)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_rxmode)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mq_mode as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(mq_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).max_rx_pkt_len - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(max_rx_pkt_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).split_hdr_size - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(split_hdr_size) - ) - ); -} -impl Default for rte_eth_rxmode { - 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 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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_eth_txmode)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_txmode)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mq_mode as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_txmode), - "::", - stringify!(mq_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pvid as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_txmode), - "::", - stringify!(pvid) - ) - ); -} -impl Default for rte_eth_txmode { - 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 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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(rte_eth_rss_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_rss_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_key as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(rss_key) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_key_len as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(rss_key_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_hf as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(rss_hf) - ) - ); -} -impl Default for rte_eth_rss_conf { - 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(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, Clone)] -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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vlan_id as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1), - "::", - stringify!(vlan_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .pools as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1), - "::", - stringify!(pools) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_conf() { - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_dcb_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .enable_default_pool as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(enable_default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).default_pool - as *const _ as usize - }, - 5usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_pool_maps - as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(nb_pool_maps) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool_map - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(pool_map) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 1032usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(dcb_tc) - ) - ); -} -impl Default for rte_eth_vmdq_dcb_conf { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_dcb_rx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_dcb_rx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_tcs as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_rx_conf), - "::", - stringify!(nb_tcs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_rx_conf), - "::", - stringify!(dcb_tc) - ) - ); -} -impl Default for rte_eth_dcb_rx_conf { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_dcb_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_tx_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_tx_conf), - "::", - stringify!(dcb_tc) - ) - ); -} -impl Default for rte_eth_vmdq_dcb_tx_conf { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_dcb_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_dcb_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_tcs as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_tx_conf), - "::", - stringify!(nb_tcs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_tx_conf), - "::", - stringify!(dcb_tc) - ) - ); -} -impl Default for rte_eth_dcb_tx_conf { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_tx_conf), - "::", - stringify!(nb_queue_pools) - ) - ); -} -impl Default for rte_eth_vmdq_tx_conf { - 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(Copy, Clone)] -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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vlan_id as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1), - "::", - stringify!(vlan_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pools - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1), - "::", - stringify!(pools) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_rx_conf() { - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_rx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_rx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).enable_default_pool - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(enable_default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).default_pool - as *const _ as usize - }, - 5usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).enable_loop_back - as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(enable_loop_back) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_pool_maps - as *const _ as usize - }, - 7usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(nb_pool_maps) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_mode as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(rx_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool_map - as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(pool_map) - ) - ); -} -impl Default for rte_eth_vmdq_rx_conf { - 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(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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_ipv4_flow)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_ipv4_flow)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_ip as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(src_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_ip as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(dst_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tos as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(tos) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ttl as *const _ - as usize - }, - 9usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(ttl) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).proto as *const _ - as usize - }, - 10usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(proto) - ) - ); -} -/// A structure used to define the input for IPV6 flow -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_eth_ipv6_flow)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_ipv6_flow)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_ip as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(src_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_ip as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(dst_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tc as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(tc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).proto as *const _ - as usize - }, - 33usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(proto) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hop_limits as *const _ - as usize - }, - 34usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(hop_limits) - ) - ); -} -/// 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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 68usize, - concat!("Size of: ", stringify!(rte_eth_fdir_masks)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_masks)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci_mask - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(vlan_tci_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ipv4_mask as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(ipv4_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ipv6_mask as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(ipv6_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_port_mask - as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(src_port_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_port_mask - as *const _ as usize - }, - 54usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(dst_port_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mac_addr_byte_mask - as *const _ as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(mac_addr_byte_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tunnel_id_mask - as *const _ as usize - }, - 60usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(tunnel_id_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tunnel_type_mask - as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(tunnel_type_mask) - ) - ); -} -#[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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_eth_flex_payload_cfg)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_flex_payload_cfg)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).type_ - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_flex_payload_cfg), - "::", - stringify!(type_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_offset - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_flex_payload_cfg), - "::", - stringify!(src_offset) - ) - ); -} -impl Default for rte_eth_flex_payload_cfg { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// A structure used to define FDIR masks for flexible payload -/// for each flow type -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 18usize, - concat!("Size of: ", stringify!(rte_eth_fdir_flex_mask)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_flex_mask)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flow_type - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_mask), - "::", - stringify!(flow_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mask as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_mask), - "::", - stringify!(mask) - ) - ); -} -/// A structure used to define all flexible payload related setting -/// include flex payload and flex mask -#[repr(C)] -#[derive(Debug, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 688usize, - concat!("Size of: ", stringify!(rte_eth_fdir_flex_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_flex_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_payloads - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(nb_payloads) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_flexmasks - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(nb_flexmasks) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_set - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(flex_set) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_mask - as *const _ as usize - }, - 292usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(flex_mask) - ) - ); -} -impl Default for rte_eth_fdir_flex_conf { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// 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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 772usize, - concat!("Size of: ", stringify!(rte_fdir_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_fdir_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mode as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pballoc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(pballoc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).status as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(status) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).drop_queue as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(drop_queue) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mask as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_conf as *const _ - as usize - }, - 84usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(flex_conf) - ) - ); -} -impl Default for rte_fdir_conf { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// A structure used to enable/disable specific device interrupts. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_intr_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_intr_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lsc as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_intr_conf), - "::", - stringify!(lsc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rxq as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_intr_conf), - "::", - stringify!(rxq) - ) - ); -} -/// 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, Clone)] -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, Clone)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 2120usize, - concat!("Size of: ", stringify!(rte_eth_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_conf__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(rss_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_dcb_conf - as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(vmdq_dcb_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_rx_conf - as *const _ as usize - }, - 1064usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(dcb_rx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_rx_conf - as *const _ as usize - }, - 1080usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(vmdq_rx_conf) - ) - ); -} -impl Default for rte_eth_conf__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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union rte_eth_conf__bindgen_ty_2 { - pub vmdq_dcb_tx_conf: rte_eth_vmdq_dcb_tx_conf, - 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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_conf__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_conf__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vmdq_dcb_tx_conf as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(vmdq_dcb_tx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tx_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(dcb_tx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_tx_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(vmdq_tx_conf) - ) - ); -} -impl Default for rte_eth_conf__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_rte_eth_conf() { - assert_eq!( - ::std::mem::size_of::(), - 2944usize, - concat!("Size of: ", stringify!(rte_eth_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).link_speeds as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(link_speeds) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rxmode as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(rxmode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).txmode as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(txmode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lpbk_mode as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(lpbk_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_adv_conf as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(rx_adv_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tx_adv_conf as *const _ - as usize - }, - 2152usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(tx_adv_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_capability_en - as *const _ as usize - }, - 2164usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(dcb_capability_en) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fdir_conf as *const _ - as usize - }, - 2168usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(fdir_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).intr_conf as *const _ - as usize - }, - 2940usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(intr_conf) - ) - ); -} -impl Default for rte_eth_conf { - 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/tests/expectations/tests/layout_eth_conf_1_0.rs b/tests/expectations/tests/layout_eth_conf_1_0.rs deleted file mode 100644 index fde1c678cf..0000000000 --- a/tests/expectations/tests/layout_eth_conf_1_0.rs +++ /dev/null @@ -1,2409 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_rxmode)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_rxmode)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mq_mode as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(mq_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).max_rx_pkt_len - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(max_rx_pkt_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).split_hdr_size - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rxmode), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_eth_txmode)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_txmode)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mq_mode as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_txmode), - "::", - stringify!(mq_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pvid as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_txmode), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(rte_eth_rss_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_rss_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_key as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(rss_key) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_key_len as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(rss_key_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_hf as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_rss_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vlan_id as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1), - "::", - stringify!(vlan_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .pools as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_dcb_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .enable_default_pool as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(enable_default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).default_pool - as *const _ as usize - }, - 5usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_pool_maps - as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(nb_pool_maps) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool_map - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(pool_map) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 1032usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_dcb_rx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_dcb_rx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_tcs as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_rx_conf), - "::", - stringify!(nb_tcs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_rx_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_dcb_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_dcb_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_tx_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_dcb_tx_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_dcb_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_dcb_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_tcs as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_tx_conf), - "::", - stringify!(nb_tcs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_dcb_tx_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_tx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_tx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_tx_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vlan_id as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1), - "::", - stringify!(vlan_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pools - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - concat!("Size of: ", stringify!(rte_eth_vmdq_rx_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_vmdq_rx_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_queue_pools - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(nb_queue_pools) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).enable_default_pool - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(enable_default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).default_pool - as *const _ as usize - }, - 5usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(default_pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).enable_loop_back - as *const _ as usize - }, - 6usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(enable_loop_back) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_pool_maps - as *const _ as usize - }, - 7usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(nb_pool_maps) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_mode as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(rx_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool_map - as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_vmdq_rx_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_ipv4_flow)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_ipv4_flow)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_ip as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(src_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_ip as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(dst_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tos as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(tos) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ttl as *const _ - as usize - }, - 9usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(ttl) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).proto as *const _ - as usize - }, - 10usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv4_flow), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_eth_ipv6_flow)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_ipv6_flow)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_ip as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(src_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_ip as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(dst_ip) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tc as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(tc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).proto as *const _ - as usize - }, - 33usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(proto) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hop_limits as *const _ - as usize - }, - 34usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_ipv6_flow), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 68usize, - concat!("Size of: ", stringify!(rte_eth_fdir_masks)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_masks)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci_mask - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(vlan_tci_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ipv4_mask as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(ipv4_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ipv6_mask as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(ipv6_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_port_mask - as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(src_port_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dst_port_mask - as *const _ as usize - }, - 54usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(dst_port_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mac_addr_byte_mask - as *const _ as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(mac_addr_byte_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tunnel_id_mask - as *const _ as usize - }, - 60usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(tunnel_id_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tunnel_type_mask - as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_masks), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(rte_eth_flex_payload_cfg)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_flex_payload_cfg)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).type_ - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_flex_payload_cfg), - "::", - stringify!(type_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_offset - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_flex_payload_cfg), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 18usize, - concat!("Size of: ", stringify!(rte_eth_fdir_flex_mask)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_flex_mask)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flow_type - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_mask), - "::", - stringify!(flow_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mask as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_mask), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 688usize, - concat!("Size of: ", stringify!(rte_eth_fdir_flex_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_fdir_flex_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_payloads - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(nb_payloads) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_flexmasks - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(nb_flexmasks) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_set - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(flex_set) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_mask - as *const _ as usize - }, - 292usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_fdir_flex_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 772usize, - concat!("Size of: ", stringify!(rte_fdir_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_fdir_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mode as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pballoc as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(pballoc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).status as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(status) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).drop_queue as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(drop_queue) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mask as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).flex_conf as *const _ - as usize - }, - 84usize, - concat!( - "Offset of field: ", - stringify!(rte_fdir_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_intr_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_intr_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lsc as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_intr_conf), - "::", - stringify!(lsc) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rxq as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(rte_intr_conf), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 2120usize, - concat!("Size of: ", stringify!(rte_eth_conf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_conf__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(rss_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_dcb_conf - as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(vmdq_dcb_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_rx_conf - as *const _ as usize - }, - 1064usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(dcb_rx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_rx_conf - as *const _ as usize - }, - 1080usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(rte_eth_conf__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_eth_conf__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .vmdq_dcb_tx_conf as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(vmdq_dcb_tx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_tx_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(dcb_tx_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vmdq_tx_conf - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf__bindgen_ty_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 2944usize, - concat!("Size of: ", stringify!(rte_eth_conf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_conf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).link_speeds as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(link_speeds) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rxmode as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(rxmode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).txmode as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(txmode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lpbk_mode as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(lpbk_mode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_adv_conf as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(rx_adv_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tx_adv_conf as *const _ - as usize - }, - 2152usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(tx_adv_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dcb_capability_en - as *const _ as usize - }, - 2164usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(dcb_capability_en) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fdir_conf as *const _ - as usize - }, - 2168usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(fdir_conf) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).intr_conf as *const _ - as usize - }, - 2940usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_conf), - "::", - stringify!(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/tests/expectations/tests/layout_kni_mbuf.rs b/tests/expectations/tests/layout_kni_mbuf.rs deleted file mode 100644 index e73344c7d0..0000000000 --- a/tests/expectations/tests/layout_kni_mbuf.rs +++ /dev/null @@ -1,231 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -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)] -pub struct rte_kni_mbuf { - pub buf_addr: *mut ::std::os::raw::c_void, - pub buf_physaddr: u64, - pub pad0: [::std::os::raw::c_char; 2usize], - ///< Start address of data in segment buffer. - pub data_off: u16, - pub pad1: [::std::os::raw::c_char; 2usize], - ///< Number of segments. - pub nb_segs: u8, - pub pad4: [::std::os::raw::c_char; 1usize], - ///< Offload features. - pub ol_flags: u64, - pub pad2: [::std::os::raw::c_char; 4usize], - ///< Total pkt len: sum of all segment data_len. - pub pkt_len: u32, - ///< Amount of data in segment buffer. - pub data_len: u16, - pub __bindgen_padding_0: [u8; 22usize], - pub pad3: [::std::os::raw::c_char; 8usize], - pub pool: *mut ::std::os::raw::c_void, - pub next: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_rte_kni_mbuf() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(rte_kni_mbuf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_kni_mbuf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_addr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(buf_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_physaddr as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(buf_physaddr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pad0 as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pad0) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_off as *const _ - as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(data_off) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pad1 as *const _ as usize - }, - 20usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pad1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_segs as *const _ - as usize - }, - 22usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(nb_segs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pad4 as *const _ as usize - }, - 23usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pad4) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ol_flags as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(ol_flags) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pad2 as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pad2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pkt_len as *const _ - as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pkt_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_len as *const _ - as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(data_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pad3 as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pad3) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).next as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_mbuf), - "::", - stringify!(next) - ) - ); -} -impl Default for rte_kni_mbuf { - 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/tests/expectations/tests/layout_large_align_field.rs b/tests/expectations/tests/layout_large_align_field.rs deleted file mode 100644 index 4208e7259c..0000000000 --- a/tests/expectations/tests/layout_large_align_field.rs +++ /dev/null @@ -1,730 +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 const 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") - } -} -pub const RTE_CACHE_LINE_SIZE: u32 = 64; -pub const RTE_LIBRTE_IP_FRAG_MAX_FRAG: u32 = 4; -pub const IP_LAST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_LAST_FRAG_IDX; -pub const IP_FIRST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_FIRST_FRAG_IDX; -pub const IP_MIN_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MIN_FRAG_NUM; -pub const IP_MAX_FRAG_NUM: _bindgen_ty_1 = _bindgen_ty_1::IP_MAX_FRAG_NUM; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - ///< index of last fragment - IP_LAST_FRAG_IDX = 0, - ///< index of first fragment - IP_FIRST_FRAG_IDX = 1, - ///< minimum number of fragments - IP_MIN_FRAG_NUM = 2, - IP_MAX_FRAG_NUM = 4, -} -/// @internal fragmented mbuf -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ip_frag { - ///< offset into the packet - pub ofs: u16, - ///< length of fragment - pub len: u16, - ///< fragment mbuf - pub mb: *mut rte_mbuf, -} -#[test] -fn bindgen_test_layout_ip_frag() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ip_frag)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ofs as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(ofs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, - 2usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mb as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_frag), - "::", - stringify!(mb) - ) - ); -} -impl Default for ip_frag { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// @internal to uniquely indetify fragmented datagram. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ip_frag_key { - ///< src address, first 8 bytes used for IPv4 - pub src_dst: [u64; 4usize], - ///< dst address - pub id: u32, - ///< src/dst key length - pub key_len: u32, -} -#[test] -fn bindgen_test_layout_ip_frag_key() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ip_frag_key)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag_key)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).src_dst as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(src_dst) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).id as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).key_len as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_key), - "::", - stringify!(key_len) - ) - ); -} -/// @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)] -pub struct ip_frag_pkt { - ///< LRU list - pub lru: ip_frag_pkt__bindgen_ty_1, - ///< fragmentation key - pub key: ip_frag_key, - ///< creation timestamp - pub start: u64, - ///< expected reassembled size - pub total_size: u32, - ///< size of fragments received - pub frag_size: u32, - ///< index of next entry to fill - pub last_idx: u32, - ///< fragments - pub frags: [ip_frag; 4usize], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ip_frag_pkt__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_frag_pkt__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqe_next - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt__bindgen_ty_1), - "::", - stringify!(tqe_next) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqe_prev - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt__bindgen_ty_1), - "::", - stringify!(tqe_prev) - ) - ); -} -impl Default for ip_frag_pkt__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() - } - } -} -#[test] -fn bindgen_test_layout_ip_frag_pkt() { - assert_eq!( - ::std::mem::size_of::(), - 192usize, - concat!("Size of: ", stringify!(ip_frag_pkt)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(ip_frag_pkt)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lru as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(lru) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).key as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(key) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).start as *const _ as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(start) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).total_size as *const _ - as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(total_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).frag_size as *const _ - as usize - }, - 68usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(frag_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).last_idx as *const _ - as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(last_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).frags as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_pkt), - "::", - stringify!(frags) - ) - ); -} -impl Default for ip_frag_pkt { - 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 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() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ip_pkt_list)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ip_pkt_list)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqh_first as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_pkt_list), - "::", - stringify!(tqh_first) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tqh_last as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_pkt_list), - "::", - stringify!(tqh_last) - ) - ); -} -impl Default for ip_pkt_list { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// fragmentation table statistics -#[repr(C)] -#[repr(align(64))] -#[derive(Copy, Clone)] -pub struct ip_frag_tbl_stat { - ///< total # of find/insert attempts. - pub find_num: u64, - ///< # of add ops. - pub add_num: u64, - ///< # of del ops. - pub del_num: u64, - ///< # of reuse (del/add) ops. - pub reuse_num: u64, - ///< total # of add failures. - pub fail_total: u64, - ///< # of 'no space' add failures. - pub fail_nospace: u64, -} -#[test] -fn bindgen_test_layout_ip_frag_tbl_stat() { - assert_eq!( - ::std::mem::size_of::(), - 64usize, - concat!("Size of: ", stringify!(ip_frag_tbl_stat)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(ip_frag_tbl_stat)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).find_num as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(find_num) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).add_num as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(add_num) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).del_num as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(del_num) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).reuse_num as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(reuse_num) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fail_total as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(fail_total) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fail_nospace - as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(ip_frag_tbl_stat), - "::", - stringify!(fail_nospace) - ) - ); -} -impl Default for ip_frag_tbl_stat { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// fragmentation table -#[repr(C)] -#[repr(align(64))] -pub struct rte_ip_frag_tbl { - ///< ttl for table entries. - pub max_cycles: u64, - ///< hash value mask. - pub entry_mask: u32, - ///< max entries allowed. - pub max_entries: u32, - ///< entries in use. - pub use_entries: u32, - ///< hash assocaitivity. - pub bucket_entries: u32, - ///< total size of the table. - pub nb_entries: u32, - ///< num of associativity lines. - pub nb_buckets: u32, - ///< last used entry. - pub last: *mut ip_frag_pkt, - ///< LRU list for table entries. - pub lru: ip_pkt_list, - pub __bindgen_padding_0: u64, - ///< statistics counters. - pub stat: ip_frag_tbl_stat, - ///< hash table. - pub pkt: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_rte_ip_frag_tbl() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(rte_ip_frag_tbl)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_ip_frag_tbl)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).max_cycles as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(max_cycles) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).entry_mask as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(entry_mask) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).max_entries as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(max_entries) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).use_entries as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(use_entries) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bucket_entries - as *const _ as usize - }, - 20usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(bucket_entries) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_entries as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(nb_entries) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_buckets as *const _ - as usize - }, - 28usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(nb_buckets) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).last as *const _ - as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(last) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lru as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(lru) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).stat as *const _ - as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(stat) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pkt as *const _ as usize - }, - 128usize, - concat!( - "Offset of field: ", - stringify!(rte_ip_frag_tbl), - "::", - stringify!(pkt) - ) - ); -} -impl Default for rte_ip_frag_tbl { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -///< fragment mbuf -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_mbuf { - pub _address: u8, -} diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs deleted file mode 100644 index aefce3d6e3..0000000000 --- a/tests/expectations/tests/layout_mbuf.rs +++ /dev/null @@ -1,1223 +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 const 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); - } - } -} -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, Clone, Hash, PartialEq, Eq)] -pub struct rte_atomic16_t { - ///< An internal counter value. - pub cnt: i16, -} -#[test] -fn bindgen_test_layout_rte_atomic16_t() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(rte_atomic16_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_atomic16_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cnt as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_atomic16_t), - "::", - stringify!(cnt) - ) - ); -} -/// The generic rte_mbuf, containing a packet mbuf. -#[repr(C)] -#[repr(align(64))] -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, -} -/// 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(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_1 { - ///< Atomically accessed refcnt - pub refcnt_atomic: rte_atomic16_t, - ///< Non-atomically accessed refcnt - pub refcnt: u16, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).refcnt_atomic - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_1), - "::", - stringify!(refcnt_atomic) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).refcnt - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_1), - "::", - stringify!(refcnt) - ) - ); -} -impl Default for rte_mbuf__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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_2 { - ///< L2/L3/L4 and tunnel information. - pub packet_type: u32, - 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 _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_2__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_2__bindgen_ty_1) - ) - ); -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).packet_type - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_2), - "::", - stringify!(packet_type) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_2 { - 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(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_3 { - ///< RSS hash result if RSS enabled - pub rss: u32, - ///< Filter identifier if FDIR enabled - pub fdir: rte_mbuf__bindgen_ty_3__bindgen_ty_1, - ///< Hierarchical scheduler - pub sched: rte_mbuf__bindgen_ty_3__bindgen_ty_2, - ///< User defined tags. See rte_distributor_process() - pub usr: u32, -} -#[repr(C)] -#[derive(Copy, Clone)] -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(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1 { - pub __bindgen_anon_1: - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - pub lo: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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( -) { - assert_eq ! (:: std :: mem :: size_of :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > () , 4usize , concat ! ("Size of: " , stringify ! (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 , concat ! ("Alignment of " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1))); - assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ())) . hash as * const _ as usize } , 0usize , concat ! ("Offset of field: " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) , "::" , stringify ! (hash))); - assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ())) . id as * const _ as usize } , 2usize , concat ! ("Offset of field: " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) , "::" , stringify ! (id))); -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - >(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - >())) - .lo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(lo) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_3__bindgen_ty_1__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() - } - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hi - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1), - "::", - stringify!(hi) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_3__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() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lo - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2), - "::", - stringify!(lo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hi - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2), - "::", - stringify!(hi) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_3)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(rss) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fdir as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(fdir) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sched as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(sched) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).usr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(usr) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_3 { - 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(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_4 { - ///< Can be used for external metadata - pub userdata: *mut ::std::os::raw::c_void, - ///< Allow 8-byte userdata on 32-bit - pub udata64: u64, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_4() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_4)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).userdata - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_4), - "::", - stringify!(userdata) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).udata64 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_4), - "::", - stringify!(udata64) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_4 { - 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(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_5 { - ///< combined for easy fetch - pub tx_offload: u64, - 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 _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_5__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_5__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_5__bindgen_ty_1) - ) - ); -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_5)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_5)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tx_offload - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_5), - "::", - stringify!(tx_offload) - ) - ); -} -impl Default for rte_mbuf__bindgen_ty_5 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_rte_mbuf() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(rte_mbuf)) - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - concat!("Alignment of ", stringify!(rte_mbuf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cacheline0 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(cacheline0) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_addr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_physaddr as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_physaddr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_len as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rearm_data as *const _ as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(rearm_data) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_off as *const _ as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(data_off) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_segs as *const _ as usize - }, - 22usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(nb_segs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).port as *const _ as usize - }, - 23usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(port) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ol_flags as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(ol_flags) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_descriptor_fields1 - as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(rx_descriptor_fields1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pkt_len as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(pkt_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_len as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(data_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci as *const _ as usize - }, - 42usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(vlan_tci) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hash as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(hash) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).seqn as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(seqn) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci_outer as *const _ - as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(vlan_tci_outer) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cacheline1 as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(cacheline1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).next as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(next) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).priv_size as *const _ as usize - }, - 96usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(priv_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).timesync as *const _ as usize - }, - 98usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(timesync) - ) - ); -} -impl Default for rte_mbuf { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -///< Pool from which mbuf was allocated. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct rte_mempool { - pub _address: u8, -} diff --git a/tests/expectations/tests/layout_mbuf_1_0.rs b/tests/expectations/tests/layout_mbuf_1_0.rs deleted file mode 100644 index ce4c66c2f0..0000000000 --- a/tests/expectations/tests/layout_mbuf_1_0.rs +++ /dev/null @@ -1,1274 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(rte_atomic16_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_atomic16_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cnt as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_atomic16_t), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).refcnt_atomic - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_1), - "::", - stringify!(refcnt_atomic) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).refcnt - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_1), - "::", - stringify!(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, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).packet_type - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_2), - "::", - stringify!(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( -) { - assert_eq ! (:: std :: mem :: size_of :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > () , 4usize , concat ! ("Size of: " , stringify ! (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 , concat ! ("Alignment of " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1))); - assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ())) . hash as * const _ as usize } , 0usize , concat ! ("Offset of field: " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) , "::" , stringify ! (hash))); - assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 > ())) . id as * const _ as usize } , 2usize , concat ! ("Offset of field: " , stringify ! (rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) , "::" , stringify ! (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() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - >(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - >())) - .lo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hi - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).lo - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2), - "::", - stringify!(lo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hi - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3__bindgen_ty_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_3)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rss as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(rss) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fdir as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(fdir) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sched as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(sched) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).usr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_3), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_4)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).userdata - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_4), - "::", - stringify!(userdata) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).udata64 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_4), - "::", - stringify!(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, - concat!( - "Size of: ", - stringify!(rte_mbuf__bindgen_ty_5__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of ", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_5)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_5)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tx_offload - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf__bindgen_ty_5), - "::", - stringify!(tx_offload) - ) - ); -} -impl Clone for rte_mbuf__bindgen_ty_5 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_mbuf() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(rte_mbuf)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cacheline0 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(cacheline0) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_addr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_addr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_physaddr as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_physaddr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buf_len as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(buf_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rearm_data as *const _ as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(rearm_data) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_off as *const _ as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(data_off) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).nb_segs as *const _ as usize - }, - 22usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(nb_segs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).port as *const _ as usize - }, - 23usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(port) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ol_flags as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(ol_flags) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).rx_descriptor_fields1 - as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(rx_descriptor_fields1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pkt_len as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(pkt_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data_len as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(data_len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci as *const _ as usize - }, - 42usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(vlan_tci) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).hash as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(hash) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).seqn as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(seqn) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).vlan_tci_outer as *const _ - as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(vlan_tci_outer) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cacheline1 as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(cacheline1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).pool as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(pool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).next as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(next) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).priv_size as *const _ as usize - }, - 96usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(priv_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).timesync as *const _ as usize - }, - 98usize, - concat!( - "Offset of field: ", - stringify!(rte_mbuf), - "::", - stringify!(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/tests/expectations/tests/libclang-4/abi_variadic_function.rs b/tests/expectations/tests/libclang-4/abi_variadic_function.rs deleted file mode 100644 index 6aeb16f2a7..0000000000 --- a/tests/expectations/tests/libclang-4/abi_variadic_function.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z1bcz"] - pub fn b(arg1: ::std::os::raw::c_char, ...) -> ::std::os::raw::c_char; -} diff --git a/tests/expectations/tests/libclang-4/auto.rs b/tests/expectations/tests/libclang-4/auto.rs deleted file mode 100644 index 0b20b39eb6..0000000000 --- a/tests/expectations/tests/libclang-4/auto.rs +++ /dev/null @@ -1,35 +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, -} -pub const Foo_kFoo: bool = true; -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_Z5Test2v"] - pub fn Test2() -> ::std::os::raw::c_uint; -} diff --git a/tests/expectations/tests/libclang-4/call-conv-field.rs b/tests/expectations/tests/libclang-4/call-conv-field.rs deleted file mode 100644 index f134bd8a46..0000000000 --- a/tests/expectations/tests/libclang-4/call-conv-field.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(not(test))] - -#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct JNINativeInterface_ { - pub GetVersion: ::std::option::Option< - unsafe extern "stdcall" fn( - env: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - >, - pub __hack: ::std::os::raw::c_ulonglong, -} -#[test] -fn bindgen_test_layout_JNINativeInterface_() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).GetVersion - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(GetVersion) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).__hack as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(__hack) - ) - ); -} -extern "stdcall" { - pub fn bar(); -} diff --git a/tests/expectations/tests/libclang-4/const_bool.rs b/tests/expectations/tests/libclang-4/const_bool.rs deleted file mode 100644 index 97e1d8dda4..0000000000 --- a/tests/expectations/tests/libclang-4/const_bool.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const k: bool = true; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub _address: u8, -} -pub const A_k: bool = false; -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} -pub type foo = bool; -pub const k2: foo = true; diff --git a/tests/expectations/tests/libclang-4/constant-evaluate.rs b/tests/expectations/tests/libclang-4/constant-evaluate.rs deleted file mode 100644 index 9debe39d3e..0000000000 --- a/tests/expectations/tests/libclang-4/constant-evaluate.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 1152921504606846976; -pub const wow: EasyToOverflow = 2147483648; -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &[u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index 57878592d9..0000000000 --- a/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 4294967291; diff --git a/tests/expectations/tests/libclang-4/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-4/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 60857966ce..0000000000 --- a/tests/expectations/tests/libclang-4/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,67 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - 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 type AutoValueVector_Alias = ::std::os::raw::c_int; - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation( - ) { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted) - ) - ); - } -} diff --git a/tests/expectations/tests/libclang-4/mangling-win32.rs b/tests/expectations/tests/libclang-4/mangling-win32.rs deleted file mode 100644 index 0aee327414..0000000000 --- a/tests/expectations/tests/libclang-4/mangling-win32.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}?sBar@Foo@@2_NA"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "fastcall" { - pub fn fast_call_func_no_args() -> ::std::os::raw::c_int; -} -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" { - pub fn std_call_func_no_args() -> ::std::os::raw::c_int; -} -extern "stdcall" { - pub fn std_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; -} diff --git a/tests/expectations/tests/libclang-4/objc_inheritance.rs b/tests/expectations/tests/libclang-4/objc_inheritance.rs deleted file mode 100644 index 5f07dbaab1..0000000000 --- a/tests/expectations/tests/libclang-4/objc_inheritance.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Bar(pub id); -impl std::ops::Deref for Bar { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Bar {} -impl Bar { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Bar), alloc) }) - } -} -impl IFoo for Bar {} -impl From for Foo { - fn from(child: Bar) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Bar { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) }; - if is_kind_of { - Ok(Bar(parent.0)) - } else { - Err("This Foo cannot be downcasted to Bar") - } - } -} -impl IBar for Bar {} -pub trait IBar: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Baz(pub id); -impl std::ops::Deref for Baz { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Baz {} -impl Baz { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Baz), alloc) }) - } -} -impl IBar for Baz {} -impl From for Bar { - fn from(child: Baz) -> Bar { - Bar(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Bar) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Bar cannot be downcasted to Baz") - } - } -} -impl IFoo for Baz {} -impl From for Foo { - fn from(child: Baz) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Foo cannot be downcasted to Baz") - } - } -} -impl IBaz for Baz {} -pub trait IBaz: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/libclang-4/objc_template.rs b/tests/expectations/tests/libclang-4/objc_template.rs deleted file mode 100644 index 36b7d22baa..0000000000 --- a/tests/expectations/tests/libclang-4/objc_template.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn get(&self) -> *mut ObjectType - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, get) - } -} -#[repr(transparent)] -#[derive(Clone)] -pub struct FooMultiGeneric(pub id); -impl std::ops::Deref for FooMultiGeneric { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for FooMultiGeneric {} -impl FooMultiGeneric { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) }) - } -} -impl - IFooMultiGeneric for FooMultiGeneric -{ -} -pub trait IFooMultiGeneric: - Sized + std::ops::Deref -{ - unsafe fn objectForKey_(&self, key: *mut KeyType) -> *mut ObjectType - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, objectForKey: key) - } -} diff --git a/tests/expectations/tests/libclang-4/partial-specialization-and-inheritance.rs b/tests/expectations/tests/libclang-4/partial-specialization-and-inheritance.rs deleted file mode 100644 index e62ea68172..0000000000 --- a/tests/expectations/tests/libclang-4/partial-specialization-and-inheritance.rs +++ /dev/null @@ -1,39 +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 Base { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Derived { - pub b: bool, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Usage { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN5Usage13static_memberE"] - pub static mut Usage_static_member: [u32; 2usize]; -} -#[test] -fn bindgen_test_layout_Usage() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Usage)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Usage)) - ); -} diff --git a/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs deleted file mode 100644 index f874e9d221..0000000000 --- a/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Rooted { - pub ptr: MaybeWrapped<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -impl Default for Rooted { - 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 type MaybeWrapped
= a; -#[test] -fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/libclang-4/wasm-constructor-returns.rs b/tests/expectations/tests/libclang-4/wasm-constructor-returns.rs deleted file mode 100644 index f207d0d8e1..0000000000 --- a/tests/expectations/tests/libclang-4/wasm-constructor-returns.rs +++ /dev/null @@ -1,37 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3FooC1Ei"] - pub fn Foo_Foo(this: *mut Foo, var: ::std::os::raw::c_int); -} -impl Foo { - #[inline] - pub unsafe fn new(var: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Foo_Foo(__bindgen_tmp.as_mut_ptr(), var); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/libclang-5/abi_variadic_function.rs b/tests/expectations/tests/libclang-5/abi_variadic_function.rs deleted file mode 100644 index 6aeb16f2a7..0000000000 --- a/tests/expectations/tests/libclang-5/abi_variadic_function.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z1bcz"] - pub fn b(arg1: ::std::os::raw::c_char, ...) -> ::std::os::raw::c_char; -} diff --git a/tests/expectations/tests/libclang-5/auto.rs b/tests/expectations/tests/libclang-5/auto.rs deleted file mode 100644 index 0b20b39eb6..0000000000 --- a/tests/expectations/tests/libclang-5/auto.rs +++ /dev/null @@ -1,35 +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, -} -pub const Foo_kFoo: bool = true; -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_Z5Test2v"] - pub fn Test2() -> ::std::os::raw::c_uint; -} diff --git a/tests/expectations/tests/libclang-5/call-conv-field.rs b/tests/expectations/tests/libclang-5/call-conv-field.rs deleted file mode 100644 index f134bd8a46..0000000000 --- a/tests/expectations/tests/libclang-5/call-conv-field.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(not(test))] - -#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct JNINativeInterface_ { - pub GetVersion: ::std::option::Option< - unsafe extern "stdcall" fn( - env: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - >, - pub __hack: ::std::os::raw::c_ulonglong, -} -#[test] -fn bindgen_test_layout_JNINativeInterface_() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).GetVersion - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(GetVersion) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).__hack as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(__hack) - ) - ); -} -extern "stdcall" { - pub fn bar(); -} diff --git a/tests/expectations/tests/libclang-5/const_bool.rs b/tests/expectations/tests/libclang-5/const_bool.rs deleted file mode 100644 index 97e1d8dda4..0000000000 --- a/tests/expectations/tests/libclang-5/const_bool.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const k: bool = true; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub _address: u8, -} -pub const A_k: bool = false; -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} -pub type foo = bool; -pub const k2: foo = true; diff --git a/tests/expectations/tests/libclang-5/constant-evaluate.rs b/tests/expectations/tests/libclang-5/constant-evaluate.rs deleted file mode 100644 index 9debe39d3e..0000000000 --- a/tests/expectations/tests/libclang-5/constant-evaluate.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 1152921504606846976; -pub const wow: EasyToOverflow = 2147483648; -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &[u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index 57878592d9..0000000000 --- a/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 4294967291; diff --git a/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 60857966ce..0000000000 --- a/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,67 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - 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 type AutoValueVector_Alias = ::std::os::raw::c_int; - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation( - ) { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted) - ) - ); - } -} diff --git a/tests/expectations/tests/libclang-5/mangling-win32.rs b/tests/expectations/tests/libclang-5/mangling-win32.rs deleted file mode 100644 index 0aee327414..0000000000 --- a/tests/expectations/tests/libclang-5/mangling-win32.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}?sBar@Foo@@2_NA"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "fastcall" { - pub fn fast_call_func_no_args() -> ::std::os::raw::c_int; -} -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" { - pub fn std_call_func_no_args() -> ::std::os::raw::c_int; -} -extern "stdcall" { - pub fn std_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; -} diff --git a/tests/expectations/tests/libclang-5/objc_inheritance.rs b/tests/expectations/tests/libclang-5/objc_inheritance.rs deleted file mode 100644 index 5f07dbaab1..0000000000 --- a/tests/expectations/tests/libclang-5/objc_inheritance.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Bar(pub id); -impl std::ops::Deref for Bar { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Bar {} -impl Bar { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Bar), alloc) }) - } -} -impl IFoo for Bar {} -impl From for Foo { - fn from(child: Bar) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Bar { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) }; - if is_kind_of { - Ok(Bar(parent.0)) - } else { - Err("This Foo cannot be downcasted to Bar") - } - } -} -impl IBar for Bar {} -pub trait IBar: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Baz(pub id); -impl std::ops::Deref for Baz { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Baz {} -impl Baz { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Baz), alloc) }) - } -} -impl IBar for Baz {} -impl From for Bar { - fn from(child: Baz) -> Bar { - Bar(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Bar) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Bar cannot be downcasted to Baz") - } - } -} -impl IFoo for Baz {} -impl From for Foo { - fn from(child: Baz) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Foo cannot be downcasted to Baz") - } - } -} -impl IBaz for Baz {} -pub trait IBaz: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/libclang-5/objc_template.rs b/tests/expectations/tests/libclang-5/objc_template.rs deleted file mode 100644 index 36b7d22baa..0000000000 --- a/tests/expectations/tests/libclang-5/objc_template.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn get(&self) -> *mut ObjectType - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, get) - } -} -#[repr(transparent)] -#[derive(Clone)] -pub struct FooMultiGeneric(pub id); -impl std::ops::Deref for FooMultiGeneric { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for FooMultiGeneric {} -impl FooMultiGeneric { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) }) - } -} -impl - IFooMultiGeneric for FooMultiGeneric -{ -} -pub trait IFooMultiGeneric: - Sized + std::ops::Deref -{ - unsafe fn objectForKey_(&self, key: *mut KeyType) -> *mut ObjectType - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, objectForKey: key) - } -} diff --git a/tests/expectations/tests/libclang-5/partial-specialization-and-inheritance.rs b/tests/expectations/tests/libclang-5/partial-specialization-and-inheritance.rs deleted file mode 100644 index e62ea68172..0000000000 --- a/tests/expectations/tests/libclang-5/partial-specialization-and-inheritance.rs +++ /dev/null @@ -1,39 +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 Base { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Derived { - pub b: bool, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Usage { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN5Usage13static_memberE"] - pub static mut Usage_static_member: [u32; 2usize]; -} -#[test] -fn bindgen_test_layout_Usage() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Usage)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Usage)) - ); -} diff --git a/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs deleted file mode 100644 index f874e9d221..0000000000 --- a/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Rooted { - pub ptr: MaybeWrapped<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -impl Default for Rooted { - 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 type MaybeWrapped
= a; -#[test] -fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/libclang-9/abi_variadic_function.rs b/tests/expectations/tests/libclang-9/abi_variadic_function.rs deleted file mode 100644 index 6aeb16f2a7..0000000000 --- a/tests/expectations/tests/libclang-9/abi_variadic_function.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z1bcz"] - pub fn b(arg1: ::std::os::raw::c_char, ...) -> ::std::os::raw::c_char; -} diff --git a/tests/expectations/tests/libclang-9/auto.rs b/tests/expectations/tests/libclang-9/auto.rs deleted file mode 100644 index 0b20b39eb6..0000000000 --- a/tests/expectations/tests/libclang-9/auto.rs +++ /dev/null @@ -1,35 +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, -} -pub const Foo_kFoo: bool = true; -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_Z5Test2v"] - pub fn Test2() -> ::std::os::raw::c_uint; -} diff --git a/tests/expectations/tests/libclang-9/call-conv-field.rs b/tests/expectations/tests/libclang-9/call-conv-field.rs deleted file mode 100644 index f134bd8a46..0000000000 --- a/tests/expectations/tests/libclang-9/call-conv-field.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(not(test))] - -#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct JNINativeInterface_ { - pub GetVersion: ::std::option::Option< - unsafe extern "stdcall" fn( - env: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, - >, - pub __hack: ::std::os::raw::c_ulonglong, -} -#[test] -fn bindgen_test_layout_JNINativeInterface_() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(JNINativeInterface_)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).GetVersion - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(GetVersion) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).__hack as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(JNINativeInterface_), - "::", - stringify!(__hack) - ) - ); -} -extern "stdcall" { - pub fn bar(); -} diff --git a/tests/expectations/tests/libclang-9/class.rs b/tests/expectations/tests/libclang-9/class.rs deleted file mode 100644 index e4527de0e2..0000000000 --- a/tests/expectations/tests/libclang-9/class.rs +++ /dev/null @@ -1,692 +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 const 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)] -#[derive(Copy, Clone)] -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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).big_array as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(big_array) - ) - ); -} -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() - } - } -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(zero_length_array) - ) - ); -} -impl Default for C_with_zero_length_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).incomplete_array - as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(incomplete_array) - ) - ); -} -impl Default for C_with_incomplete_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .incomplete_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .big_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(zero_length_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .incomplete_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(incomplete_array) - ) - ); -} -impl Default for C_with_zero_length_array_and_incomplete_array { - 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, 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() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - ::std::mem::align_of::( - ), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(zero_length_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .incomplete_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(incomplete_array) - ) - ); -} -#[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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithDtor)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithDtor), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -pub struct IncompleteArrayNonCopiable { - pub whatever: *mut ::std::os::raw::c_void, - pub incomplete_array: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).whatever - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(IncompleteArrayNonCopiable), - "::", - stringify!(whatever) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .incomplete_array as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(IncompleteArrayNonCopiable), - "::", - stringify!(incomplete_array) - ) - ); -} -impl Default for IncompleteArrayNonCopiable { - 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(Copy, Clone)] -pub union Union { - pub d: f32, - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Union() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Union)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Union)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(i)) - ); -} -impl Default for 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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct WithUnion { - pub data: Union, -} -#[test] -fn bindgen_test_layout_WithUnion() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithUnion), - "::", - stringify!(data) - ) - ); -} -impl Default for WithUnion { - 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, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct RealAbstractionWithTonsOfMethods { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(RealAbstractionWithTonsOfMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(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 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/tests/expectations/tests/libclang-9/class_1_0.rs b/tests/expectations/tests/libclang-9/class_1_0.rs deleted file mode 100644 index 4263bd144c..0000000000 --- a/tests/expectations/tests/libclang-9/class_1_0.rs +++ /dev/null @@ -1,743 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).big_array as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_zero_length_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).big_array - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).incomplete_array - as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .incomplete_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_incomplete_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .big_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(big_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .zero_length_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(zero_length_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array, - >())) - .incomplete_array as *const _ as usize - }, - 37usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::( - ), - 4usize, - concat!( - "Size of: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - ::std::mem::align_of::( - ), - 4usize, - concat!( - "Alignment of ", - stringify!(C_with_zero_length_array_and_incomplete_array_2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .zero_length_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(zero_length_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - C_with_zero_length_array_and_incomplete_array_2, - >())) - .incomplete_array as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C_with_zero_length_array_and_incomplete_array_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithDtor)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithDtor), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -pub struct IncompleteArrayNonCopiable { - pub whatever: *mut ::std::os::raw::c_void, - pub incomplete_array: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).whatever - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(IncompleteArrayNonCopiable), - "::", - stringify!(whatever) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .incomplete_array as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(IncompleteArrayNonCopiable), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Union)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Union)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Union), "::", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).data as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithUnion), - "::", - stringify!(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, - concat!("Size of: ", stringify!(RealAbstractionWithTonsOfMethods)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(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/tests/expectations/tests/libclang-9/const_bool.rs b/tests/expectations/tests/libclang-9/const_bool.rs deleted file mode 100644 index 97e1d8dda4..0000000000 --- a/tests/expectations/tests/libclang-9/const_bool.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const k: bool = true; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub _address: u8, -} -pub const A_k: bool = false; -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(A)) - ); -} -pub type foo = bool; -pub const k2: foo = true; diff --git a/tests/expectations/tests/libclang-9/constant-evaluate.rs b/tests/expectations/tests/libclang-9/constant-evaluate.rs deleted file mode 100644 index 9debe39d3e..0000000000 --- a/tests/expectations/tests/libclang-9/constant-evaluate.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 1152921504606846976; -pub const wow: EasyToOverflow = 2147483648; -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &[u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-9/derive-hash-struct-with-incomplete-array.rs b/tests/expectations/tests/libclang-9/derive-hash-struct-with-incomplete-array.rs deleted file mode 100644 index 32607b375f..0000000000 --- a/tests/expectations/tests/libclang-9/derive-hash-struct-with-incomplete-array.rs +++ /dev/null @@ -1,162 +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 const 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)] -#[derive(Debug, Default)] -pub struct test { - pub a: ::std::os::raw::c_int, - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_test() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(test), "::", stringify!(a)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).zero_length_array as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(test), - "::", - stringify!(zero_length_array) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct test2 { - pub a: ::std::os::raw::c_int, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_test2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test2)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(test2), "::", stringify!(a)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).incomplete_array as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(test2), - "::", - stringify!(incomplete_array) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct test3 { - 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_test3() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(test3)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(test3)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(test3), "::", stringify!(a)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).zero_length_array as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(test3), - "::", - stringify!(zero_length_array) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).incomplete_array as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(test3), - "::", - stringify!(incomplete_array) - ) - ); -} diff --git a/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index 57878592d9..0000000000 --- a/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 4294967291; diff --git a/tests/expectations/tests/libclang-9/incomplete-array-padding.rs b/tests/expectations/tests/libclang-9/incomplete-array-padding.rs deleted file mode 100644 index 382195dbb9..0000000000 --- a/tests/expectations/tests/libclang-9/incomplete-array-padding.rs +++ /dev/null @@ -1,184 +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 const 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)] -#[derive(Default)] -pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); -impl __IncompleteArrayField { - #[inline] - pub const 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)] -#[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>, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) - ); -} -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 a(&self) -> ::std::os::raw::c_char { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_char) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - a: ::std::os::raw::c_char, - ) -> __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 - } -} diff --git a/tests/expectations/tests/libclang-9/issue-643-inner-struct.rs b/tests/expectations/tests/libclang-9/issue-643-inner-struct.rs deleted file mode 100644 index 49664cdd5e..0000000000 --- a/tests/expectations/tests/libclang-9/issue-643-inner-struct.rs +++ /dev/null @@ -1,182 +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 const 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)] -#[derive(Debug)] -pub struct rte_ring { - pub memzone: *mut rte_memzone, - pub prod: rte_ring_prod, - pub cons: rte_ring_cons, - pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_ring_prod { - pub watermark: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_rte_ring_prod() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ring_prod)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ring_prod)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).watermark as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ring_prod), - "::", - stringify!(watermark) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_ring_cons { - pub sc_dequeue: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_rte_ring_cons() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(rte_ring_cons)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(rte_ring_cons)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sc_dequeue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ring_cons), - "::", - stringify!(sc_dequeue) - ) - ); -} -#[test] -fn bindgen_test_layout_rte_ring() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_ring)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_ring)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).memzone as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_ring), - "::", - stringify!(memzone) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).prod as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_ring), - "::", - stringify!(prod) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cons as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(rte_ring), - "::", - stringify!(cons) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ring as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_ring), - "::", - stringify!(ring) - ) - ); -} -impl Default for rte_ring { - 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, Default, Copy, Clone)] -pub struct rte_memzone { - pub _address: u8, -} diff --git a/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 60857966ce..0000000000 --- a/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,67 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - 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 type AutoValueVector_Alias = ::std::os::raw::c_int; - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted<::std::os::raw::c_int>) - ) - ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation( - ) { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(root::Rooted) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::Rooted) - ) - ); - } -} diff --git a/tests/expectations/tests/libclang-9/layout_align.rs b/tests/expectations/tests/libclang-9/layout_align.rs deleted file mode 100644 index 4ad5417577..0000000000 --- a/tests/expectations/tests/libclang-9/layout_align.rs +++ /dev/null @@ -1,322 +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 const 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)] -#[derive(Default)] -pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); -impl __IncompleteArrayField { - #[inline] - pub const 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)] -#[derive(Debug)] -pub struct rte_kni_fifo { - ///< Next position to be written - pub write: ::std::os::raw::c_uint, - ///< Next position to be read - pub read: ::std::os::raw::c_uint, - ///< Circular buffer length - pub len: ::std::os::raw::c_uint, - ///< Pointer size - for 32/64 bit OS - pub elem_size: ::std::os::raw::c_uint, - ///< The buffer contains mbuf pointers - pub buffer: __IncompleteArrayField<*mut ::std::os::raw::c_void>, -} -#[test] -fn bindgen_test_layout_rte_kni_fifo() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(rte_kni_fifo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_kni_fifo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).write as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_fifo), - "::", - stringify!(write) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).read as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_fifo), - "::", - stringify!(read) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).len as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_fifo), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).elem_size as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_fifo), - "::", - stringify!(elem_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).buffer as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(rte_kni_fifo), - "::", - stringify!(buffer) - ) - ); -} -impl Default for rte_kni_fifo { - 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)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct rte_eth_link { - ///< 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], -} -#[test] -fn bindgen_test_layout_rte_eth_link() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(rte_eth_link)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(rte_eth_link)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).link_speed as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(rte_eth_link), - "::", - stringify!(link_speed) - ) - ); -} -impl rte_eth_link { - #[inline] - pub fn link_duplex(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_duplex(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn link_autoneg(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_autoneg(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(1usize, 1u8, val as u64) - } - } - #[inline] - pub fn link_status(&self) -> u16 { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) - } - } - #[inline] - pub fn set_link_status(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(2usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - link_duplex: u16, - link_autoneg: u16, - link_status: u16, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let link_duplex: u16 = - unsafe { ::std::mem::transmute(link_duplex) }; - link_duplex as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let link_autoneg: u16 = - unsafe { ::std::mem::transmute(link_autoneg) }; - link_autoneg as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let link_status: u16 = - unsafe { ::std::mem::transmute(link_status) }; - link_status as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/libclang-9/mangling-win32.rs b/tests/expectations/tests/libclang-9/mangling-win32.rs deleted file mode 100644 index 0aee327414..0000000000 --- a/tests/expectations/tests/libclang-9/mangling-win32.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}?sBar@Foo@@2_NA"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "fastcall" { - pub fn fast_call_func_no_args() -> ::std::os::raw::c_int; -} -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" { - pub fn std_call_func_no_args() -> ::std::os::raw::c_int; -} -extern "stdcall" { - pub fn std_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; -} diff --git a/tests/expectations/tests/libclang-9/objc_inheritance.rs b/tests/expectations/tests/libclang-9/objc_inheritance.rs deleted file mode 100644 index 5f07dbaab1..0000000000 --- a/tests/expectations/tests/libclang-9/objc_inheritance.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Bar(pub id); -impl std::ops::Deref for Bar { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Bar {} -impl Bar { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Bar), alloc) }) - } -} -impl IFoo for Bar {} -impl From for Foo { - fn from(child: Bar) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Bar { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) }; - if is_kind_of { - Ok(Bar(parent.0)) - } else { - Err("This Foo cannot be downcasted to Bar") - } - } -} -impl IBar for Bar {} -pub trait IBar: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Baz(pub id); -impl std::ops::Deref for Baz { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Baz {} -impl Baz { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Baz), alloc) }) - } -} -impl IBar for Baz {} -impl From for Bar { - fn from(child: Baz) -> Bar { - Bar(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Bar) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Bar cannot be downcasted to Baz") - } - } -} -impl IFoo for Baz {} -impl From for Foo { - fn from(child: Baz) -> Foo { - Foo(child.0) - } -} -impl std::convert::TryFrom for Baz { - type Error = &'static str; - fn try_from(parent: Foo) -> Result { - let is_kind_of: bool = - unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) }; - if is_kind_of { - Ok(Baz(parent.0)) - } else { - Err("This Foo cannot be downcasted to Baz") - } - } -} -impl IBaz for Baz {} -pub trait IBaz: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/libclang-9/objc_template.rs b/tests/expectations/tests/libclang-9/objc_template.rs deleted file mode 100644 index 88cf209bdf..0000000000 --- a/tests/expectations/tests/libclang-9/objc_template.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn get(&self) -> u64 - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, get) - } -} -#[repr(transparent)] -#[derive(Clone)] -pub struct FooMultiGeneric(pub id); -impl std::ops::Deref for FooMultiGeneric { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for FooMultiGeneric {} -impl FooMultiGeneric { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) }) - } -} -impl - IFooMultiGeneric for FooMultiGeneric -{ -} -pub trait IFooMultiGeneric: - Sized + std::ops::Deref -{ - unsafe fn objectForKey_(&self, key: u64) -> u64 - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, objectForKey: key) - } -} diff --git a/tests/expectations/tests/libclang-9/partial-specialization-and-inheritance.rs b/tests/expectations/tests/libclang-9/partial-specialization-and-inheritance.rs deleted file mode 100644 index e62ea68172..0000000000 --- a/tests/expectations/tests/libclang-9/partial-specialization-and-inheritance.rs +++ /dev/null @@ -1,39 +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 Base { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Derived { - pub b: bool, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Usage { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN5Usage13static_memberE"] - pub static mut Usage_static_member: [u32; 2usize]; -} -#[test] -fn bindgen_test_layout_Usage() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Usage)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Usage)) - ); -} diff --git a/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs deleted file mode 100644 index f874e9d221..0000000000 --- a/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Rooted { - pub ptr: MaybeWrapped<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -impl Default for Rooted { - 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 type MaybeWrapped
= a; -#[test] -fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/libclang-9/zero-sized-array.rs b/tests/expectations/tests/libclang-9/zero-sized-array.rs deleted file mode 100644 index 6514b930c7..0000000000 --- a/tests/expectations/tests/libclang-9/zero-sized-array.rs +++ /dev/null @@ -1,184 +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 const 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") - } -} -/// Bizarrely enough, this should *not* get an `_address` field. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ZeroSizedArray { - pub arr: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_ZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ZeroSizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ZeroSizedArray), - "::", - stringify!(arr) - ) - ); -} -/// And nor should this get an `_address` field. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ContainsZeroSizedArray { - pub zsa: ZeroSizedArray, -} -#[test] -fn bindgen_test_layout_ContainsZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ContainsZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsZeroSizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).zsa as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsZeroSizedArray), - "::", - stringify!(zsa) - ) - ); -} -/// Inheriting from ZeroSizedArray shouldn't cause an `_address` to be inserted -/// either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct InheritsZeroSizedArray { - pub _base: ZeroSizedArray, -} -#[test] -fn bindgen_test_layout_InheritsZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(InheritsZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(InheritsZeroSizedArray)) - ); -} -/// And this should not get an `_address` field either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct DynamicallySizedArray { - pub arr: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DynamicallySizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(DynamicallySizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(DynamicallySizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arr as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(DynamicallySizedArray), - "::", - stringify!(arr) - ) - ); -} -/// No `_address` field here either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ContainsDynamicallySizedArray { - pub dsa: DynamicallySizedArray, -} -#[test] -fn bindgen_test_layout_ContainsDynamicallySizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ContainsDynamicallySizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsDynamicallySizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).dsa - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsDynamicallySizedArray), - "::", - stringify!(dsa) - ) - ); -} diff --git a/tests/expectations/tests/long_double.rs b/tests/expectations/tests/long_double.rs deleted file mode 100644 index dbd4248ee5..0000000000 --- a/tests/expectations/tests/long_double.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(16))] -#[derive(Debug, Default, Copy, Clone)] -pub struct foo { - pub bar: u128, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/macro-expr-basic.rs b/tests/expectations/tests/macro-expr-basic.rs deleted file mode 100644 index 4eeb310c8f..0000000000 --- a/tests/expectations/tests/macro-expr-basic.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const FOO: u32 = 1; -pub const BAR: u32 = 4; -pub const BAZ: u32 = 5; -pub const MIN: i64 = -9223372036854775808; -pub const BARR: u32 = 1; -pub const BAZZ: u32 = 7; -pub const I_RAN_OUT_OF_DUMB_NAMES: u32 = 7; -pub const HAZ_A_COMMENT: u32 = 1; -pub const HAZ_A_COMMENT_INSIDE: u32 = 2; diff --git a/tests/expectations/tests/macro-expr-uncommon-token.rs b/tests/expectations/tests/macro-expr-uncommon-token.rs deleted file mode 100644 index b2f2ebd2e2..0000000000 --- a/tests/expectations/tests/macro-expr-uncommon-token.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const MODBUS_WOOT: u32 = 3; -extern "C" { - pub fn foo(); -} diff --git a/tests/expectations/tests/macro-redef.rs b/tests/expectations/tests/macro-redef.rs deleted file mode 100644 index ff5654f47b..0000000000 --- a/tests/expectations/tests/macro-redef.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const FOO: u32 = 4; -pub const BAR: u32 = 5; -pub const BAZ: u32 = 6; diff --git a/tests/expectations/tests/macro_const.rs b/tests/expectations/tests/macro_const.rs deleted file mode 100644 index de423a2af0..0000000000 --- a/tests/expectations/tests/macro_const.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: &[u8; 4usize] = 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: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/macro_const_1_0.rs b/tests/expectations/tests/macro_const_1_0.rs deleted file mode 100644 index e135661121..0000000000 --- a/tests/expectations/tests/macro_const_1_0.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: &'static [u8; 4usize] = 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: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/maddness-is-avoidable.rs b/tests/expectations/tests/maddness-is-avoidable.rs deleted file mode 100644 index 12157f4b9d..0000000000 --- a/tests/expectations/tests/maddness-is-avoidable.rs +++ /dev/null @@ -1,17 +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 RefPtr { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct RefPtr_Proxy { - pub _address: u8, -} diff --git a/tests/expectations/tests/mangling-ios.rs b/tests/expectations/tests/mangling-ios.rs deleted file mode 100644 index 8a4ff6578e..0000000000 --- a/tests/expectations/tests/mangling-ios.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} diff --git a/tests/expectations/tests/mangling-linux32.rs b/tests/expectations/tests/mangling-linux32.rs deleted file mode 100644 index bddd761794..0000000000 --- a/tests/expectations/tests/mangling-linux32.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo4sBarE"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/mangling-linux64.rs b/tests/expectations/tests/mangling-linux64.rs deleted file mode 100644 index bddd761794..0000000000 --- a/tests/expectations/tests/mangling-linux64.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo4sBarE"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/mangling-macos.rs b/tests/expectations/tests/mangling-macos.rs deleted file mode 100644 index 9af36259fd..0000000000 --- a/tests/expectations/tests/mangling-macos.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}__ZN3Foo4sBarE"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/mangling-win64.rs b/tests/expectations/tests/mangling-win64.rs deleted file mode 100644 index cb5f7103ad..0000000000 --- a/tests/expectations/tests/mangling-win64.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}?sBar@Foo@@2_NA"] - pub static mut Foo_sBar: bool; -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} diff --git a/tests/expectations/tests/method-mangling.rs b/tests/expectations/tests/method-mangling.rs deleted file mode 100644 index e4627ac8a7..0000000000 --- a/tests/expectations/tests/method-mangling.rs +++ /dev/null @@ -1,35 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3Foo4typeEv"] - pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_int; -} -impl Foo { - #[inline] - pub unsafe fn type_(&mut self) -> ::std::os::raw::c_int { - Foo_type(self) - } -} diff --git a/tests/expectations/tests/module-allowlisted.rs b/tests/expectations/tests/module-allowlisted.rs deleted file mode 100644 index 30cdb3580b..0000000000 --- a/tests/expectations/tests/module-allowlisted.rs +++ /dev/null @@ -1,30 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Test { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); - } -} diff --git a/tests/expectations/tests/msvc-no-usr.rs b/tests/expectations/tests/msvc-no-usr.rs deleted file mode 100644 index ea5a90b871..0000000000 --- a/tests/expectations/tests/msvc-no-usr.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type size_t = ::std::os::raw::c_ulonglong; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct A { - pub foo: size_t, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(foo)) - ); -} diff --git a/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs b/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs deleted file mode 100644 index 55b3d1e31b..0000000000 --- a/tests/expectations/tests/multiple-inherit-empty-correct-layout.rs +++ /dev/null @@ -1,61 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Baz { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Baz)) - ); -} diff --git a/tests/expectations/tests/mutable.rs b/tests/expectations/tests/mutable.rs deleted file mode 100644 index 9f5865fccc..0000000000 --- a/tests/expectations/tests/mutable.rs +++ /dev/null @@ -1,114 +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 C { - pub m_member: ::std::os::raw::c_int, - pub m_other: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m_member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(m_member) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m_other as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(m_other) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct NonCopiable { - pub m_member: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NonCopiable() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NonCopiable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NonCopiable)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).m_member as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NonCopiable), - "::", - stringify!(m_member) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct NonCopiableWithNonCopiableMutableMember { - pub m_member: NonCopiable, -} -#[test] -fn bindgen_test_layout_NonCopiableWithNonCopiableMutableMember() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!( - "Size of: ", - stringify!(NonCopiableWithNonCopiableMutableMember) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(NonCopiableWithNonCopiableMutableMember) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .m_member as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NonCopiableWithNonCopiableMutableMember), - "::", - stringify!(m_member) - ) - ); -} diff --git a/tests/expectations/tests/namespace.rs b/tests/expectations/tests/namespace.rs deleted file mode 100644 index 576fc9336f..0000000000 --- a/tests/expectations/tests/namespace.rs +++ /dev/null @@ -1,125 +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 { - #[allow(unused_imports)] - use self::super::root; - extern "C" { - #[link_name = "\u{1}_Z9top_levelv"] - pub fn top_level(); - } - pub mod whatever { - #[allow(unused_imports)] - 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" { - #[link_name = "\u{1}_ZN8whatever11in_whateverEv"] - pub fn in_whatever(); - } - } - pub mod _bindgen_mod_id_17 { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct A { - pub b: root::whatever::whatever_int_t, - } - #[test] - fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(A), - "::", - stringify!(b) - ) - ); - } - } - #[repr(C)] - #[derive(Debug)] - pub struct C { - pub _base: root::_bindgen_mod_id_17::A, - pub m_c: T, - pub m_c_ptr: *mut T, - pub m_c_arr: [T; 10usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - 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() - } - } - } - pub mod w { - #[allow(unused_imports)] - use self::super::super::root; - pub type whatever_int_t = ::std::os::raw::c_uint; - #[repr(C)] - #[derive(Debug)] - pub struct D { - pub m_c: root::C, - pub _phantom_0: - ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for D { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } - } - extern "C" { - #[link_name = "\u{1}_ZN1w3hehEv"] - pub fn heh() -> root::w::whatever_int_t; - } - extern "C" { - #[link_name = "\u{1}_ZN1w3fooEv"] - pub fn foo() -> root::C<::std::os::raw::c_int>; - } - extern "C" { - #[link_name = "\u{1}_ZN1w4barrEv"] - pub fn barr() -> root::C; - } - } - pub mod foobar { - #[allow(unused_imports)] - use self::super::super::root; - extern "C" { - #[link_name = "\u{1}_ZN6foobar3fooEv"] - pub fn foo(); - } - } - pub mod faraway { - #[allow(unused_imports)] - use self::super::super::root; - extern "C" { - #[link_name = "\u{1}_ZN7faraway3barEv"] - pub fn bar(); - } - } -} diff --git a/tests/expectations/tests/nested-template-typedef.rs b/tests/expectations/tests/nested-template-typedef.rs deleted file mode 100644 index ab761d286f..0000000000 --- a/tests/expectations/tests/nested-template-typedef.rs +++ /dev/null @@ -1,17 +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, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo_Bar { - pub _address: u8, -} diff --git a/tests/expectations/tests/nested.rs b/tests/expectations/tests/nested.rs deleted file mode 100644 index 92cd6605b4..0000000000 --- a/tests/expectations/tests/nested.rs +++ /dev/null @@ -1,109 +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 Calc { - pub w: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Calc() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Calc)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Calc)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).w as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Calc), "::", stringify!(w)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Test { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Test_Size { - pub mWidth: Test_Size_Dimension, - pub mHeight: Test_Size_Dimension, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Test_Size_Dimension { - pub _base: Calc, -} -#[test] -fn bindgen_test_layout_Test_Size_Dimension() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Test_Size_Dimension)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Test_Size_Dimension)) - ); -} -#[test] -fn bindgen_test_layout_Test_Size() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Test_Size)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Test_Size)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mWidth as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Test_Size), - "::", - stringify!(mWidth) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mHeight as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(Test_Size), - "::", - stringify!(mHeight) - ) - ); -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); -} diff --git a/tests/expectations/tests/nested_vtable.rs b/tests/expectations/tests/nested_vtable.rs deleted file mode 100644 index 7ee483044e..0000000000 --- a/tests/expectations/tests/nested_vtable.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct nsISupports__bindgen_vtable { - pub nsISupports_QueryInterface: - unsafe extern "C" fn(this: *mut nsISupports) -> *mut nsISupports, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct nsISupports { - pub vtable_: *const nsISupports__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_nsISupports() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsISupports)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsISupports)) - ); -} -impl Default for nsISupports { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_ZN11nsISupports14QueryInterfaceEv"] - pub fn nsISupports_QueryInterface( - this: *mut ::std::os::raw::c_void, - ) -> *mut nsISupports; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct nsIRunnable { - pub _base: nsISupports, -} -#[test] -fn bindgen_test_layout_nsIRunnable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsIRunnable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsIRunnable)) - ); -} -impl Default for nsIRunnable { - 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 Runnable { - pub _base: nsIRunnable, -} -#[test] -fn bindgen_test_layout_Runnable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Runnable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Runnable)) - ); -} -impl Default for Runnable { - 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/tests/expectations/tests/nested_within_namespace.rs b/tests/expectations/tests/nested_within_namespace.rs deleted file mode 100644 index 86b9b8c68b..0000000000 --- a/tests/expectations/tests/nested_within_namespace.rs +++ /dev/null @@ -1,106 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar { - pub foo: ::std::os::raw::c_int, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar_Baz { - pub foo: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_Bar_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar_Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar_Baz)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar_Baz), - "::", - stringify!(foo) - ) - ); - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(foo) - ) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Baz { - pub baz: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Baz)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).baz as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Baz), - "::", - stringify!(baz) - ) - ); - } - } -} diff --git a/tests/expectations/tests/newtype-enum.rs b/tests/expectations/tests/newtype-enum.rs deleted file mode 100644 index 26a4eb1fdf..0000000000 --- a/tests/expectations/tests/newtype-enum.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![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)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Foo(pub ::std::os::raw::c_int); diff --git a/tests/expectations/tests/no-comments.rs b/tests/expectations/tests/no-comments.rs deleted file mode 100644 index 7a9d0d82b5..0000000000 --- a/tests/expectations/tests/no-comments.rs +++ /dev/null @@ -1,30 +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 s: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).s as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(s)) - ); -} diff --git a/tests/expectations/tests/no-derive-debug.rs b/tests/expectations/tests/no-derive-debug.rs deleted file mode 100644 index a62eaa5df5..0000000000 --- a/tests/expectations/tests/no-derive-debug.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct foo { - bar: ::std::os::raw::c_int, -} - -/// bar should compile. It will normally derive debug, but our blocklist of foo -/// and replacement for another type that doesn't implement it would prevent it -/// from building if --no-derive-debug didn't work. -#[repr(C)] -pub struct bar { - pub foo: foo, - pub baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(bar), "::", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(bar), "::", stringify!(baz)) - ); -} -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/tests/expectations/tests/no-derive-default.rs b/tests/expectations/tests/no-derive-default.rs deleted file mode 100644 index eda13aad68..0000000000 --- a/tests/expectations/tests/no-derive-default.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct foo { - bar: ::std::os::raw::c_int, -} - -/// bar should compile. It will normally derive default, but our blocklist of foo -/// and replacement for another type that doesn't implement it would prevent it -/// from building if --no-derive-default didn't work. -#[repr(C)] -pub struct bar { - pub foo: foo, - pub baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(bar), "::", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(bar), "::", stringify!(baz)) - ); -} diff --git a/tests/expectations/tests/no-hash-allowlisted.rs b/tests/expectations/tests/no-hash-allowlisted.rs deleted file mode 100644 index 1cd7f672b6..0000000000 --- a/tests/expectations/tests/no-hash-allowlisted.rs +++ /dev/null @@ -1,30 +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 NoHash { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NoHash() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoHash)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoHash)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(NoHash), "::", stringify!(i)) - ); -} diff --git a/tests/expectations/tests/no-hash-opaque.rs b/tests/expectations/tests/no-hash-opaque.rs deleted file mode 100644 index 49ff4daad7..0000000000 --- a/tests/expectations/tests/no-hash-opaque.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct NoHash { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_NoHash() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoHash)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoHash)) - ); -} diff --git a/tests/expectations/tests/no-partialeq-allowlisted.rs b/tests/expectations/tests/no-partialeq-allowlisted.rs deleted file mode 100644 index cd3ed3b935..0000000000 --- a/tests/expectations/tests/no-partialeq-allowlisted.rs +++ /dev/null @@ -1,37 +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 NoPartialEq { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NoPartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoPartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoPartialEq)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NoPartialEq), - "::", - stringify!(i) - ) - ); -} diff --git a/tests/expectations/tests/no-partialeq-opaque.rs b/tests/expectations/tests/no-partialeq-opaque.rs deleted file mode 100644 index 423799a6b9..0000000000 --- a/tests/expectations/tests/no-partialeq-opaque.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct NoPartialEq { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_NoPartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoPartialEq)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoPartialEq)) - ); -} diff --git a/tests/expectations/tests/no-recursive-allowlisting.rs b/tests/expectations/tests/no-recursive-allowlisting.rs deleted file mode 100644 index 0aa0b5e322..0000000000 --- a/tests/expectations/tests/no-recursive-allowlisting.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub enum Bar {} - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - pub baz: *mut Bar, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Foo), "::", stringify!(baz)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/no-std.rs b/tests/expectations/tests/no-std.rs deleted file mode 100644 index f63ac4512b..0000000000 --- a/tests/expectations/tests/no-std.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![no_std] -mod libc { - pub type c_int = i32; - pub enum c_void {} -} - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct foo { - pub a: libc::c_int, - pub b: libc::c_int, - pub bar: *mut libc::c_void, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).b as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).bar as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Default for foo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} diff --git a/tests/expectations/tests/no_copy.rs b/tests/expectations/tests/no_copy.rs deleted file mode 100644 index daccf757ec..0000000000 --- a/tests/expectations/tests/no_copy.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[derive(Debug, Default)] -pub struct CopiableButWait { - pub whatever: ::std::os::raw::c_int, -} diff --git a/tests/expectations/tests/no_copy_allowlisted.rs b/tests/expectations/tests/no_copy_allowlisted.rs deleted file mode 100644 index fa53bb66fe..0000000000 --- a/tests/expectations/tests/no_copy_allowlisted.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct NoCopy { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NoCopy() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoCopy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoCopy)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(NoCopy), "::", stringify!(i)) - ); -} diff --git a/tests/expectations/tests/no_copy_opaque.rs b/tests/expectations/tests/no_copy_opaque.rs deleted file mode 100644 index 7fc3529f6e..0000000000 --- a/tests/expectations/tests/no_copy_opaque.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default)] -pub struct NoCopy { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_NoCopy() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoCopy)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoCopy)) - ); -} diff --git a/tests/expectations/tests/no_debug.rs b/tests/expectations/tests/no_debug.rs deleted file mode 100644 index 21850ecb15..0000000000 --- a/tests/expectations/tests/no_debug.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct DebugButWait { - pub whatever: ::std::os::raw::c_int, -} diff --git a/tests/expectations/tests/no_debug_allowlisted.rs b/tests/expectations/tests/no_debug_allowlisted.rs deleted file mode 100644 index e240d645fb..0000000000 --- a/tests/expectations/tests/no_debug_allowlisted.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Default, Copy, Clone)] -pub struct NoDebug { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NoDebug() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoDebug)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoDebug)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NoDebug), - "::", - stringify!(i) - ) - ); -} diff --git a/tests/expectations/tests/no_debug_bypass_impl_debug.rs b/tests/expectations/tests/no_debug_bypass_impl_debug.rs deleted file mode 100644 index 334f39ddb0..0000000000 --- a/tests/expectations/tests/no_debug_bypass_impl_debug.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Generic { - pub t: [T; 40usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Generic { - 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 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 t: [T; 40usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for NoDebug { - 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/tests/expectations/tests/no_debug_opaque.rs b/tests/expectations/tests/no_debug_opaque.rs deleted file mode 100644 index 4b657481cd..0000000000 --- a/tests/expectations/tests/no_debug_opaque.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(4))] -#[derive(Default, Copy, Clone)] -pub struct NoDebug { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_NoDebug() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoDebug)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoDebug)) - ); -} diff --git a/tests/expectations/tests/no_default_allowlisted.rs b/tests/expectations/tests/no_default_allowlisted.rs deleted file mode 100644 index 980f1575f0..0000000000 --- a/tests/expectations/tests/no_default_allowlisted.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct NoDefault { - pub i: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_NoDefault() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoDefault)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoDefault)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).i as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NoDefault), - "::", - stringify!(i) - ) - ); -} diff --git a/tests/expectations/tests/no_default_opaque.rs b/tests/expectations/tests/no_default_opaque.rs deleted file mode 100644 index 3c928551e6..0000000000 --- a/tests/expectations/tests/no_default_opaque.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Copy, Clone)] -pub struct NoDefault { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_NoDefault() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(NoDefault)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(NoDefault)) - ); -} diff --git a/tests/expectations/tests/non-type-params.rs b/tests/expectations/tests/non-type-params.rs deleted file mode 100644 index acd7a09f3a..0000000000 --- a/tests/expectations/tests/non-type-params.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Array16 = u8; -pub type ArrayInt4 = [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_int_4: ArrayInt4, -} -#[test] -fn bindgen_test_layout_UsesArray() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(UsesArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(UsesArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).array_char_16 as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(UsesArray), - "::", - stringify!(array_char_16) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).array_bool_8 as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(UsesArray), - "::", - stringify!(array_bool_8) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).array_int_4 as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(UsesArray), - "::", - stringify!(array_int_4) - ) - ); -} diff --git a/tests/expectations/tests/objc_allowlist.rs b/tests/expectations/tests/objc_allowlist.rs deleted file mode 100644 index dcec0fd12e..0000000000 --- a/tests/expectations/tests/objc_allowlist.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -impl AllowlistMe_InterestingCategory for AllowlistMe {} -pub trait AllowlistMe_InterestingCategory: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/objc_category.rs b/tests/expectations/tests/objc_category.rs deleted file mode 100644 index e0328c708f..0000000000 --- a/tests/expectations/tests/objc_category.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(&self) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, method) - } -} -impl Foo_BarCategory for Foo {} -pub trait Foo_BarCategory: Sized + std::ops::Deref { - unsafe fn categoryMethod(&self) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, categoryMethod) - } -} diff --git a/tests/expectations/tests/objc_class.rs b/tests/expectations/tests/objc_class.rs deleted file mode 100644 index 5a8a71d164..0000000000 --- a/tests/expectations/tests/objc_class.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -extern "C" { - pub static mut fooVar: Foo; -} -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(&self) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, method) - } -} diff --git a/tests/expectations/tests/objc_interface.rs b/tests/expectations/tests/objc_interface.rs deleted file mode 100644 index c5ba2758b9..0000000000 --- a/tests/expectations/tests/objc_interface.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} -pub trait Pbar: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/objc_interface_type.rs b/tests/expectations/tests/objc_interface_type.rs deleted file mode 100644 index cef29c8c96..0000000000 --- a/tests/expectations/tests/objc_interface_type.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FooStruct { - pub foo: Foo, -} -#[test] -fn bindgen_test_layout_FooStruct() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(FooStruct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(FooStruct)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(FooStruct), - "::", - stringify!(foo) - ) - ); -} -impl Default for FooStruct { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - pub fn fooFunc(foo: Foo); -} -extern "C" { - pub static mut kFoo: Foo; -} diff --git a/tests/expectations/tests/objc_method.rs b/tests/expectations/tests/objc_method.rs deleted file mode 100644 index af5c6093db..0000000000 --- a/tests/expectations/tests/objc_method.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(&self) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, method) - } - unsafe fn methodWithInt_(&self, foo: ::std::os::raw::c_int) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, methodWithInt: foo) - } - unsafe fn methodWithFoo_(&self, foo: Foo) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, methodWithFoo: foo) - } - unsafe fn methodReturningInt(&self) -> ::std::os::raw::c_int - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, methodReturningInt) - } - unsafe fn methodReturningFoo(&self) -> Foo - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, methodReturningFoo) - } - unsafe fn methodWithArg1_andArg2_andArg3_( - &self, - intvalue: ::std::os::raw::c_int, - ptr: *mut ::std::os::raw::c_char, - floatvalue: f32, - ) where - ::Target: objc::Message + Sized, - { - msg_send ! (* self , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue) - } - unsafe fn methodWithAndWithoutKeywords_arg2Name__arg4Name_( - &self, - arg1: ::std::os::raw::c_int, - arg2: f32, - arg3: f32, - arg4: ::std::os::raw::c_int, - ) -> instancetype - where - ::Target: objc::Message + Sized, - { - msg_send ! (* self , methodWithAndWithoutKeywords : arg1 arg2Name : arg2 arg3 : arg3 arg4Name : arg4) - } -} -pub type instancetype = id; diff --git a/tests/expectations/tests/objc_method_clash.rs b/tests/expectations/tests/objc_method_clash.rs deleted file mode 100644 index 8370f33fc2..0000000000 --- a/tests/expectations/tests/objc_method_clash.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref { - unsafe fn foo(&self) - where - ::Target: objc::Message + Sized, - { - msg_send!(*self, foo) - } - unsafe fn class_foo() - where - ::Target: objc::Message + Sized, - { - msg_send!(class!(Foo), foo) - } -} diff --git a/tests/expectations/tests/objc_protocol.rs b/tests/expectations/tests/objc_protocol.rs deleted file mode 100644 index e68ddcc1d2..0000000000 --- a/tests/expectations/tests/objc_protocol.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -pub trait PFoo: Sized + std::ops::Deref {} -#[repr(transparent)] -#[derive(Clone)] -pub struct Foo(pub id); -impl std::ops::Deref for Foo { - type Target = objc::runtime::Object; - fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } - } -} -unsafe impl objc::Message for Foo {} -impl Foo { - pub fn alloc() -> Self { - Self(unsafe { msg_send!(objc::class!(Foo), alloc) }) - } -} -impl PFoo for Foo {} -impl IFoo for Foo {} -pub trait IFoo: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/objc_sel_and_id.rs b/tests/expectations/tests/objc_sel_and_id.rs deleted file mode 100644 index 2a389093df..0000000000 --- a/tests/expectations/tests/objc_sel_and_id.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(target_os = "macos")] - -#[macro_use] -extern crate objc; -#[allow(non_camel_case_types)] -pub type id = *mut objc::runtime::Object; -extern "C" { - pub static mut object: id; -} -extern "C" { - pub static mut selector: objc::runtime::Sel; -} -extern "C" { - pub fn f(object: id, selector: objc::runtime::Sel); -} diff --git a/tests/expectations/tests/only_bitfields.rs b/tests/expectations/tests/only_bitfields.rs deleted file mode 100644 index 2f063b5b38..0000000000 --- a/tests/expectations/tests/only_bitfields.rs +++ /dev/null @@ -1,157 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct C { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(C)) - ); -} -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 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 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/tests/expectations/tests/opaque-template-inst-member-2.rs b/tests/expectations/tests/opaque-template-inst-member-2.rs deleted file mode 100644 index f47aff0552..0000000000 --- a/tests/expectations/tests/opaque-template-inst-member-2.rs +++ /dev/null @@ -1,102 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// This is like `opaque-template-inst-member.hpp` except exercising the cases -/// where we are OK to derive Debug/Hash/PartialEq. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct OpaqueTemplate { - pub _address: u8, -} -/// Should derive Debug/Hash/PartialEq. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ContainsOpaqueTemplate { - pub mBlah: u32, - pub mBaz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ContainsOpaqueTemplate() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ContainsOpaqueTemplate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ContainsOpaqueTemplate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBlah as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueTemplate), - "::", - stringify!(mBlah) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBaz as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueTemplate), - "::", - stringify!(mBaz) - ) - ); -} -/// Should also derive Debug/Hash/PartialEq. -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct InheritsOpaqueTemplate { - pub _base: u8, - pub wow: *mut ::std::os::raw::c_char, -} -#[test] -fn bindgen_test_layout_InheritsOpaqueTemplate() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(InheritsOpaqueTemplate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(InheritsOpaqueTemplate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).wow as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(InheritsOpaqueTemplate), - "::", - stringify!(wow) - ) - ); -} -impl Default for InheritsOpaqueTemplate { - 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/tests/expectations/tests/opaque-template-inst-member.rs b/tests/expectations/tests/opaque-template-inst-member.rs deleted file mode 100644 index a3c67784de..0000000000 --- a/tests/expectations/tests/opaque-template-inst-member.rs +++ /dev/null @@ -1,119 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct OpaqueTemplate { - pub _address: u8, -} -/// 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)] -pub struct ContainsOpaqueTemplate { - pub mBlah: [u32; 101usize], - pub mBaz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ContainsOpaqueTemplate() { - assert_eq!( - ::std::mem::size_of::(), - 408usize, - concat!("Size of: ", stringify!(ContainsOpaqueTemplate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ContainsOpaqueTemplate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBlah as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueTemplate), - "::", - stringify!(mBlah) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBaz as *const _ - as usize - }, - 404usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueTemplate), - "::", - stringify!(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 - } -} -/// This should not end up deriving Debug/Hash either, for similar reasons, although -/// we're exercising base member edges now. -#[repr(C)] -pub struct InheritsOpaqueTemplate { - pub _base: [u8; 401usize], - pub wow: *mut ::std::os::raw::c_char, -} -#[test] -fn bindgen_test_layout_InheritsOpaqueTemplate() { - assert_eq!( - ::std::mem::size_of::(), - 416usize, - concat!("Size of: ", stringify!(InheritsOpaqueTemplate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(InheritsOpaqueTemplate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).wow as *const _ - as usize - }, - 408usize, - concat!( - "Offset of field: ", - stringify!(InheritsOpaqueTemplate), - "::", - stringify!(wow) - ) - ); -} -impl Default for InheritsOpaqueTemplate { - 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 InheritsOpaqueTemplate { - fn eq(&self, other: &InheritsOpaqueTemplate) -> bool { - &self._base[..] == &other._base[..] && self.wow == other.wow - } -} diff --git a/tests/expectations/tests/opaque-template-instantiation-namespaced.rs b/tests/expectations/tests/opaque-template-instantiation-namespaced.rs deleted file mode 100644 index e972443ed3..0000000000 --- a/tests/expectations/tests/opaque-template-instantiation-namespaced.rs +++ /dev/null @@ -1,187 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod zoidberg { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub struct Template { - pub member: T, - pub _phantom_0: - ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Template { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] - pub struct Foo { - pub c: ::std::os::raw::c_char, - } - #[test] - fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Foo), - "::", - stringify!(c) - ) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] - pub struct Bar { - pub i: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(i) - ) - ); - } - #[repr(C)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub struct ContainsInstantiation { - pub not_opaque: root::zoidberg::Template, - } - #[test] - fn bindgen_test_layout_ContainsInstantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ContainsInstantiation)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsInstantiation)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).not_opaque - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsInstantiation), - "::", - stringify!(not_opaque) - ) - ); - } - impl Default for ContainsInstantiation { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] - pub struct ContainsOpaqueInstantiation { - pub opaque: u32, - } - #[test] - fn bindgen_test_layout_ContainsOpaqueInstantiation() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(ContainsOpaqueInstantiation)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(ContainsOpaqueInstantiation) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .opaque as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueInstantiation), - "::", - stringify!(opaque) - ) - ); - } - } - #[test] - fn __bindgen_test_layout_Template_open0_Foo_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>( - ), - 1usize, - concat!( - "Size of template specialization: ", - stringify!(root::zoidberg::Template) - ) - ); - assert_eq!( - ::std::mem::align_of::>( - ), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(root::zoidberg::Template) - ) - ); - } -} diff --git a/tests/expectations/tests/opaque-template-instantiation.rs b/tests/expectations/tests/opaque-template-instantiation.rs deleted file mode 100644 index 6f0f31b376..0000000000 --- a/tests/expectations/tests/opaque-template-instantiation.rs +++ /dev/null @@ -1,112 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Template { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Template { - 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, Hash, PartialEq, Eq)] -pub struct ContainsInstantiation { - pub not_opaque: Template<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_ContainsInstantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(ContainsInstantiation)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsInstantiation)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).not_opaque - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsInstantiation), - "::", - stringify!(not_opaque) - ) - ); -} -impl Default for ContainsInstantiation { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ContainsOpaqueInstantiation { - pub opaque: u32, -} -#[test] -fn bindgen_test_layout_ContainsOpaqueInstantiation() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(ContainsOpaqueInstantiation)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ContainsOpaqueInstantiation)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).opaque - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsOpaqueInstantiation), - "::", - stringify!(opaque) - ) - ); -} -#[test] -fn __bindgen_test_layout_Template_open0_char_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 1usize, - concat!( - "Size of template specialization: ", - stringify!(Template<::std::os::raw::c_char>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(Template<::std::os::raw::c_char>) - ) - ); -} diff --git a/tests/expectations/tests/opaque-tracing.rs b/tests/expectations/tests/opaque-tracing.rs deleted file mode 100644 index 98c5417138..0000000000 --- a/tests/expectations/tests/opaque-tracing.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z3fooP9Container"] - pub fn foo(c: *mut Container); -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Container { - pub _bindgen_opaque_blob: [u32; 2usize], -} -#[test] -fn bindgen_test_layout_Container() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Container)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Container)) - ); -} diff --git a/tests/expectations/tests/opaque_in_struct.rs b/tests/expectations/tests/opaque_in_struct.rs deleted file mode 100644 index 980df3d612..0000000000 --- a/tests/expectations/tests/opaque_in_struct.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct opaque { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_opaque() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(opaque)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(opaque)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct container { - pub contained: opaque, -} -#[test] -fn bindgen_test_layout_container() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(container)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(container)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).contained as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(container), - "::", - stringify!(contained) - ) - ); -} diff --git a/tests/expectations/tests/opaque_pointer.rs b/tests/expectations/tests/opaque_pointer.rs deleted file mode 100644 index 90b019b290..0000000000 --- a/tests/expectations/tests/opaque_pointer.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -///
-#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct OtherOpaque { - pub _bindgen_opaque_blob: u32, -} -#[test] -fn bindgen_test_layout_OtherOpaque() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(OtherOpaque)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(OtherOpaque)) - ); -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Opaque { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq)] -pub struct WithOpaquePtr { - pub whatever: *mut u8, - pub other: u32, - pub t: OtherOpaque, -} -#[test] -fn bindgen_test_layout_WithOpaquePtr() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(WithOpaquePtr)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(WithOpaquePtr)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).whatever as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithOpaquePtr), - "::", - stringify!(whatever) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).other as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(WithOpaquePtr), - "::", - stringify!(other) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).t as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(WithOpaquePtr), - "::", - stringify!(t) - ) - ); -} -impl Default for WithOpaquePtr { - 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/tests/expectations/tests/opaque_typedef.rs b/tests/expectations/tests/opaque_typedef.rs deleted file mode 100644 index c61a294cf6..0000000000 --- a/tests/expectations/tests/opaque_typedef.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct RandomTemplate { - pub _address: u8, -} -///
-pub type ShouldBeOpaque = u8; -pub type ShouldNotBeOpaque = RandomTemplate; diff --git a/tests/expectations/tests/operator.rs b/tests/expectations/tests/operator.rs deleted file mode 100644 index 5128226dd8..0000000000 --- a/tests/expectations/tests/operator.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z20operator_informationv"] - pub fn operator_information() -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Foo { - _unused: [u8; 0], -} diff --git a/tests/expectations/tests/ord-enum.rs b/tests/expectations/tests/ord-enum.rs deleted file mode 100644 index a72fef8df6..0000000000 --- a/tests/expectations/tests/ord-enum.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub enum A { - A0 = 0, - A1 = 1, - A2 = 2, - A3 = -1, -} -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub enum B { - B0 = 1, - B1 = 4, - B2 = 3, - B3 = -1, -} diff --git a/tests/expectations/tests/overflowed_enum.rs b/tests/expectations/tests/overflowed_enum.rs deleted file mode 100644 index 94e166addb..0000000000 --- a/tests/expectations/tests/overflowed_enum.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Foo { - BAP_ARM = 9698489, - BAP_X86 = 11960045, - BAP_X86_64 = 3128633167, -} -#[repr(u16)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum Bar { - One = 1, - Big = 2, -} diff --git a/tests/expectations/tests/overloading.rs b/tests/expectations/tests/overloading.rs deleted file mode 100644 index b43432eb0d..0000000000 --- a/tests/expectations/tests/overloading.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z8Evaluatec"] - pub fn Evaluate(r: ::std::os::raw::c_char) -> bool; -} -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" { - #[link_name = "\u{1}_ZN3foo10MyFunctionEv"] - pub fn foo_MyFunction(); -} -extern "C" { - #[link_name = "\u{1}_ZN3bar10MyFunctionEv"] - pub fn bar_MyFunction(); -} diff --git a/tests/expectations/tests/packed-bitfield.rs b/tests/expectations/tests/packed-bitfield.rs deleted file mode 100644 index f90edb930b..0000000000 --- a/tests/expectations/tests/packed-bitfield.rs +++ /dev/null @@ -1,175 +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 const 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, packed)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Date { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, -} -#[test] -fn bindgen_test_layout_Date() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(Date)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Date)) - ); -} -impl Date { - #[inline] - pub fn day(&self) -> ::std::os::raw::c_uchar { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 5u8) as u8) - } - } - #[inline] - pub fn set_day(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_month(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_year(&mut self, val: ::std::os::raw::c_short) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(9usize, 15u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - day: ::std::os::raw::c_uchar, - month: ::std::os::raw::c_uchar, - year: ::std::os::raw::c_short, - ) -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 5u8, { - let day: u8 = unsafe { ::std::mem::transmute(day) }; - day as u64 - }); - __bindgen_bitfield_unit.set(5usize, 4u8, { - let month: u8 = unsafe { ::std::mem::transmute(month) }; - month as u64 - }); - __bindgen_bitfield_unit.set(9usize, 15u8, { - let year: u16 = unsafe { ::std::mem::transmute(year) }; - year as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/packed-n-with-padding.rs b/tests/expectations/tests/packed-n-with-padding.rs deleted file mode 100644 index 13cb030620..0000000000 --- a/tests/expectations/tests/packed-n-with-padding.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C, packed(2))] -#[derive(Debug, Default, Copy, Clone)] -pub struct Packed { - pub a: ::std::os::raw::c_char, - pub b: ::std::os::raw::c_short, - pub c: ::std::os::raw::c_char, - pub d: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Packed() { - assert_eq!( - ::std::mem::size_of::(), - 10usize, - concat!("Size of: ", stringify!(Packed)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(Packed)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Packed), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 2usize, - concat!("Offset of field: ", stringify!(Packed), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Packed), "::", stringify!(c)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 6usize, - concat!("Offset of field: ", stringify!(Packed), "::", stringify!(d)) - ); -} diff --git a/tests/expectations/tests/packed-vtable.rs b/tests/expectations/tests/packed-vtable.rs deleted file mode 100644 index 0069eada96..0000000000 --- a/tests/expectations/tests/packed-vtable.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(feature = "nightly")] - -#[repr(C)] -pub struct PackedVtable__bindgen_vtable(::std::os::raw::c_void); -#[repr(C, packed)] -#[derive(Debug)] -pub struct PackedVtable { - pub vtable_: *const PackedVtable__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_PackedVtable() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PackedVtable)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(PackedVtable)) - ); -} -impl Default for PackedVtable { - 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}_ZN12PackedVtableD1Ev"] - pub fn PackedVtable_PackedVtable_destructor(this: *mut PackedVtable); -} diff --git a/tests/expectations/tests/parm-union.rs b/tests/expectations/tests/parm-union.rs deleted file mode 100644 index 9f7dd20ad9..0000000000 --- a/tests/expectations/tests/parm-union.rs +++ /dev/null @@ -1,40 +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 Struct { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Struct() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Struct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Struct)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN6Struct8FunctionER5Union"] - pub fn Struct_Function(this: *mut Struct, arg1: *mut Union); -} -impl Struct { - #[inline] - pub unsafe fn Function(&mut self, arg1: *mut Union) { - Struct_Function(self, arg1) - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Union { - _unused: [u8; 0], -} diff --git a/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs b/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs deleted file mode 100644 index e615486ed8..0000000000 --- a/tests/expectations/tests/parsecb-anonymous-enum-variant-rename.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const RENAMED_MyVal: ::std::os::raw::c_uint = 0; -pub type _bindgen_ty_1 = ::std::os::raw::c_uint; diff --git a/tests/expectations/tests/prepend-enum-constified-variant.rs b/tests/expectations/tests/prepend-enum-constified-variant.rs deleted file mode 100644 index b2b094443b..0000000000 --- a/tests/expectations/tests/prepend-enum-constified-variant.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -impl AVCodecID { - pub const AV_CODEC_ID_TTF: AVCodecID = AVCodecID::AV_CODEC_ID_FIRST_UNKNOWN; -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum AVCodecID { - AV_CODEC_ID_FIRST_UNKNOWN = 98304, -} diff --git a/tests/expectations/tests/prepend_enum_name.rs b/tests/expectations/tests/prepend_enum_name.rs deleted file mode 100644 index 31db41444c..0000000000 --- a/tests/expectations/tests/prepend_enum_name.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const FOO_BAR: foo = 0; -pub const FOO_BAZ: foo = 1; -pub type foo = ::std::os::raw::c_uint; diff --git a/tests/expectations/tests/private.rs b/tests/expectations/tests/private.rs deleted file mode 100644 index 328f97f08f..0000000000 --- a/tests/expectations/tests/private.rs +++ /dev/null @@ -1,146 +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 HasPrivate { - pub mNotPrivate: ::std::os::raw::c_int, - ///
- mIsPrivate: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_HasPrivate() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(HasPrivate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(HasPrivate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mNotPrivate as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(HasPrivate), - "::", - stringify!(mNotPrivate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsPrivate as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(HasPrivate), - "::", - stringify!(mIsPrivate) - ) - ); -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct VeryPrivate { - mIsPrivate: ::std::os::raw::c_int, - mIsAlsoPrivate: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_VeryPrivate() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(VeryPrivate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(VeryPrivate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsPrivate as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(VeryPrivate), - "::", - stringify!(mIsPrivate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsAlsoPrivate as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(VeryPrivate), - "::", - stringify!(mIsAlsoPrivate) - ) - ); -} -///
-#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ContradictPrivate { - ///
- pub mNotPrivate: ::std::os::raw::c_int, - mIsPrivate: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_ContradictPrivate() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ContradictPrivate)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(ContradictPrivate)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mNotPrivate - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContradictPrivate), - "::", - stringify!(mNotPrivate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsPrivate as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(ContradictPrivate), - "::", - stringify!(mIsPrivate) - ) - ); -} diff --git a/tests/expectations/tests/private_fields.rs b/tests/expectations/tests/private_fields.rs deleted file mode 100644 index 92a4bf653b..0000000000 --- a/tests/expectations/tests/private_fields.rs +++ /dev/null @@ -1,529 +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 const 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)] -#[derive(Debug, Default, Copy, Clone)] -pub struct PubPriv { - pub x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_PubPriv() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PubPriv)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(PubPriv)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PubPriv), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).y as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(PubPriv), - "::", - stringify!(y) - ) - ); -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct PrivateBitFields { - pub _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], -} -#[test] -fn bindgen_test_layout_PrivateBitFields() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(PrivateBitFields)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(PrivateBitFields)) - ); -} -impl PrivateBitFields { - #[inline] - fn a(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) - } - } - #[inline] - fn set_a(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - fn set_b(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(4usize, 4u8, val as u64) - } - } - #[inline] - fn new_bitfield_1( - a: ::std::os::raw::c_uint, - b: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct PublicBitFields { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], -} -#[test] -fn bindgen_test_layout_PublicBitFields() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(PublicBitFields)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(PublicBitFields)) - ); -} -impl PublicBitFields { - #[inline] - pub fn a(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(4usize, 4u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - a: ::std::os::raw::c_uint, - b: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone)] -pub struct MixedBitFields { - pub _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], -} -#[test] -fn bindgen_test_layout_MixedBitFields() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(MixedBitFields)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(MixedBitFields)) - ); -} -impl MixedBitFields { - #[inline] - fn a(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) - } - } - #[inline] - fn set_a(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_d(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(4usize, 4u8, val as u64) - } - } - #[inline] - fn new_bitfield_1( - a: ::std::os::raw::c_uint, - d: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let d: u32 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Base { - pub member: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Base() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Base)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).member as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Base), - "::", - stringify!(member) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct InheritsPrivately { - _base: Base, -} -#[test] -fn bindgen_test_layout_InheritsPrivately() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(InheritsPrivately)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(InheritsPrivately)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct InheritsPublically { - pub _base: Base, -} -#[test] -fn bindgen_test_layout_InheritsPublically() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(InheritsPublically)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(InheritsPublically)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct WithAnonStruct { - __bindgen_anon_1: WithAnonStruct__bindgen_ty_1, - pub __bindgen_anon_2: WithAnonStruct__bindgen_ty_2, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct WithAnonStruct__bindgen_ty_1 { - pub a: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_WithAnonStruct__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithAnonStruct__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithAnonStruct__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithAnonStruct__bindgen_ty_1), - "::", - stringify!(a) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct WithAnonStruct__bindgen_ty_2 { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_WithAnonStruct__bindgen_ty_2() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(WithAnonStruct__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithAnonStruct__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithAnonStruct__bindgen_ty_2), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_WithAnonStruct() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(WithAnonStruct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithAnonStruct)) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct WithAnonUnion { - __bindgen_anon_1: WithAnonUnion__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union WithAnonUnion__bindgen_ty_1 { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_WithAnonUnion__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(WithAnonUnion__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(WithAnonUnion__bindgen_ty_1)) - ); -} -impl Default for WithAnonUnion__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() - } - } -} -#[test] -fn bindgen_test_layout_WithAnonUnion() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(WithAnonUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(WithAnonUnion)) - ); -} -impl Default for WithAnonUnion { - 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/tests/expectations/tests/public-dtor.rs b/tests/expectations/tests/public-dtor.rs deleted file mode 100644 index 64a503899e..0000000000 --- a/tests/expectations/tests/public-dtor.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default)] -pub struct cv_String { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_cv_String() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(cv_String)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(cv_String)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN2cv6StringD1Ev"] - pub fn cv_String_String_destructor(this: *mut cv_String); -} -impl cv_String { - #[inline] - pub unsafe fn destruct(&mut self) { - cv_String_String_destructor(self) - } -} diff --git a/tests/expectations/tests/qualified-dependent-types.rs b/tests/expectations/tests/qualified-dependent-types.rs deleted file mode 100644 index f1b2c8459c..0000000000 --- a/tests/expectations/tests/qualified-dependent-types.rs +++ /dev/null @@ -1,17 +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, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} diff --git a/tests/expectations/tests/redeclaration.rs b/tests/expectations/tests/redeclaration.rs deleted file mode 100644 index 8a4ff6578e..0000000000 --- a/tests/expectations/tests/redeclaration.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn foo(); -} diff --git a/tests/expectations/tests/ref_argument_array.rs b/tests/expectations/tests/ref_argument_array.rs deleted file mode 100644 index 00a8e0ee35..0000000000 --- a/tests/expectations/tests/ref_argument_array.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const NSID_LENGTH: u32 = 10; -#[repr(C)] -pub struct nsID__bindgen_vtable { - pub nsID_ToProvidedString: unsafe extern "C" fn( - this: *mut nsID, - aDest: *mut [::std::os::raw::c_char; 10usize], - ), -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct nsID { - pub vtable_: *const nsID__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_nsID() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsID)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsID)) - ); -} -impl Default for nsID { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_ZN4nsID16ToProvidedStringERA10_c"] - pub fn nsID_ToProvidedString( - this: *mut ::std::os::raw::c_void, - aDest: *mut [::std::os::raw::c_char; 10usize], - ); -} diff --git a/tests/expectations/tests/reparented_replacement.rs b/tests/expectations/tests/reparented_replacement.rs deleted file mode 100644 index 1f4fa6e1b8..0000000000 --- a/tests/expectations/tests/reparented_replacement.rs +++ /dev/null @@ -1,48 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod foo { - #[allow(unused_imports)] - use self::super::super::root; - ///
- #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Bar { - pub bazz: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).bazz as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(bazz) - ) - ); - } - } - pub type ReferencesBar = root::foo::Bar; -} diff --git a/tests/expectations/tests/replace_template_alias.rs b/tests/expectations/tests/replace_template_alias.rs deleted file mode 100644 index 4f464129fe..0000000000 --- a/tests/expectations/tests/replace_template_alias.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// But the replacement type does use T! -/// -///
-pub type JS_detail_MaybeWrapped = T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct JS_Rooted { - pub ptr: JS_detail_MaybeWrapped, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for JS_Rooted { - 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/tests/expectations/tests/replace_use.rs b/tests/expectations/tests/replace_use.rs deleted file mode 100644 index 7bec94b8d2..0000000000 --- a/tests/expectations/tests/replace_use.rs +++ /dev/null @@ -1,52 +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 nsTArray { - pub y: ::std::os::raw::c_uint, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Test { - pub a: nsTArray, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(a)) - ); -} -#[test] -fn __bindgen_test_layout_nsTArray_open0_long_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of template specialization: ", stringify!(nsTArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(nsTArray) - ) - ); -} diff --git a/tests/expectations/tests/repr-align.rs b/tests/expectations/tests/repr-align.rs deleted file mode 100644 index df2353686a..0000000000 --- a/tests/expectations/tests/repr-align.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(feature = "nightly")] - -#[repr(C)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct a { - pub b: ::std::os::raw::c_int, - pub c: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::
(), - 8usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(c)) - ); -} -#[repr(C)] -#[repr(align(8))] -#[derive(Debug, Default, Copy, Clone)] -pub struct b { - pub b: ::std::os::raw::c_int, - pub c: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_b() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(b)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(b), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(b), "::", stringify!(c)) - ); -} diff --git a/tests/expectations/tests/resolved_type_def_function.rs b/tests/expectations/tests/resolved_type_def_function.rs deleted file mode 100644 index 797976798f..0000000000 --- a/tests/expectations/tests/resolved_type_def_function.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type FuncType = ::std::option::Option; -extern "C" { - pub fn Func(); -} diff --git a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs b/tests/expectations/tests/same_struct_name_in_different_namespaces.rs deleted file mode 100644 index 056b671b33..0000000000 --- a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct JS_Zone { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct JS_shadow_Zone { - pub x: ::std::os::raw::c_int, - pub y: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_JS_shadow_Zone() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(JS_shadow_Zone)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(JS_shadow_Zone)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(JS_shadow_Zone), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(JS_shadow_Zone), - "::", - stringify!(y) - ) - ); -} diff --git a/tests/expectations/tests/sentry-defined-multiple-times.rs b/tests/expectations/tests/sentry-defined-multiple-times.rs deleted file mode 100644 index 5f2ec54d5a..0000000000 --- a/tests/expectations/tests/sentry-defined-multiple-times.rs +++ /dev/null @@ -1,363 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod whatever { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Wrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct Wrapper_sentry { - pub i_am_wrapper_sentry: ::std::os::raw::c_int, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct sentry { - pub i_am_plain_sentry: bool, - } - #[test] - fn bindgen_test_layout_sentry() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(sentry)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(sentry)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i_am_plain_sentry - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(sentry), - "::", - stringify!(i_am_plain_sentry) - ) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct NotTemplateWrapper { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_NotTemplateWrapper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(NotTemplateWrapper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(NotTemplateWrapper)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct NotTemplateWrapper_sentry { - pub i_am_not_template_wrapper_sentry: ::std::os::raw::c_char, - } - #[test] - fn bindgen_test_layout_NotTemplateWrapper_sentry() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(NotTemplateWrapper_sentry)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(NotTemplateWrapper_sentry)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .i_am_not_template_wrapper_sentry - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(NotTemplateWrapper_sentry), - "::", - stringify!(i_am_not_template_wrapper_sentry) - ) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct InlineNotTemplateWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct InlineNotTemplateWrapper_sentry { - pub i_am_inline_not_template_wrapper_sentry: bool, - } - #[test] - fn bindgen_test_layout_InlineNotTemplateWrapper_sentry() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!( - "Size of: ", - stringify!(InlineNotTemplateWrapper_sentry) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(InlineNotTemplateWrapper_sentry) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())) - .i_am_inline_not_template_wrapper_sentry - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(InlineNotTemplateWrapper_sentry), - "::", - stringify!(i_am_inline_not_template_wrapper_sentry) - ) - ); - } - #[test] - fn bindgen_test_layout_InlineNotTemplateWrapper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(InlineNotTemplateWrapper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(InlineNotTemplateWrapper)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct InlineTemplateWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct InlineTemplateWrapper_sentry { - pub i_am_inline_template_wrapper_sentry: ::std::os::raw::c_int, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleWrapper_InnerDoubleWrapper { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_OuterDoubleWrapper_InnerDoubleWrapper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!( - "Size of: ", - stringify!(OuterDoubleWrapper_InnerDoubleWrapper) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!( - "Alignment of ", - stringify!(OuterDoubleWrapper_InnerDoubleWrapper) - ) - ); - } - #[test] - fn bindgen_test_layout_OuterDoubleWrapper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(OuterDoubleWrapper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(OuterDoubleWrapper)) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleWrapper_InnerDoubleWrapper_sentry { - pub i_am_double_wrapper_sentry: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_OuterDoubleWrapper_InnerDoubleWrapper_sentry() { - assert_eq!( - ::std::mem::size_of::< - OuterDoubleWrapper_InnerDoubleWrapper_sentry, - >(), - 4usize, - concat!( - "Size of: ", - stringify!(OuterDoubleWrapper_InnerDoubleWrapper_sentry) - ) - ); - assert_eq!( - ::std::mem::align_of::< - OuterDoubleWrapper_InnerDoubleWrapper_sentry, - >(), - 4usize, - concat!( - "Alignment of ", - stringify!(OuterDoubleWrapper_InnerDoubleWrapper_sentry) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::< - OuterDoubleWrapper_InnerDoubleWrapper_sentry, - >())) - .i_am_double_wrapper_sentry as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(OuterDoubleWrapper_InnerDoubleWrapper_sentry), - "::", - stringify!(i_am_double_wrapper_sentry) - ) - ); - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleInlineWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleInlineWrapper_InnerDoubleInlineWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry { - pub i_am_double_wrapper_inline_sentry: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry( - ) { - assert_eq ! (:: std :: mem :: size_of :: < OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry > () , 4usize , concat ! ("Size of: " , stringify ! (OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry))); - assert_eq ! (:: std :: mem :: align_of :: < OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry > () , 4usize , concat ! ("Alignment of " , stringify ! (OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry))); - assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry > ())) . i_am_double_wrapper_inline_sentry as * const _ as usize } , 0usize , concat ! ("Offset of field: " , stringify ! (OuterDoubleInlineWrapper_InnerDoubleInlineWrapper_sentry) , "::" , stringify ! (i_am_double_wrapper_inline_sentry))); - } - #[test] - fn bindgen_test_layout_OuterDoubleInlineWrapper_InnerDoubleInlineWrapper( - ) { - assert_eq!( - ::std::mem::size_of::< - OuterDoubleInlineWrapper_InnerDoubleInlineWrapper, - >(), - 1usize, - concat!( - "Size of: ", - stringify!( - OuterDoubleInlineWrapper_InnerDoubleInlineWrapper - ) - ) - ); - assert_eq!( - ::std::mem::align_of::< - OuterDoubleInlineWrapper_InnerDoubleInlineWrapper, - >(), - 1usize, - concat!( - "Alignment of ", - stringify!( - OuterDoubleInlineWrapper_InnerDoubleInlineWrapper - ) - ) - ); - } - #[test] - fn bindgen_test_layout_OuterDoubleInlineWrapper() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(OuterDoubleInlineWrapper)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(OuterDoubleInlineWrapper)) - ); - } - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OutsideNamespaceWrapper { - pub _address: u8, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct OutsideNamespaceWrapper_sentry { - pub i_am_outside_namespace_wrapper_sentry: ::std::os::raw::c_int, - } - #[repr(C)] - #[derive(Debug, Default, Copy, Clone)] - pub struct sentry { - pub i_am_outside_namespace_sentry: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_sentry() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(sentry)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(sentry)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i_am_outside_namespace_sentry - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(sentry), - "::", - stringify!(i_am_outside_namespace_sentry) - ) - ); - } -} diff --git a/tests/expectations/tests/size_t_is_usize.rs b/tests/expectations/tests/size_t_is_usize.rs deleted file mode 100644 index 0d9ab2caba..0000000000 --- a/tests/expectations/tests/size_t_is_usize.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct A { - pub len: usize, - pub offset: isize, - pub next: *mut A, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(len)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).offset as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(offset)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).next as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(next)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/size_t_template.rs b/tests/expectations/tests/size_t_template.rs deleted file mode 100644 index 6796bc9f3a..0000000000 --- a/tests/expectations/tests/size_t_template.rs +++ /dev/null @@ -1,30 +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 C { - pub arr: [u32; 3usize], -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).arr as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(arr)) - ); -} diff --git a/tests/expectations/tests/struct_containing_forward_declared_struct.rs b/tests/expectations/tests/struct_containing_forward_declared_struct.rs deleted file mode 100644 index 7298095e21..0000000000 --- a/tests/expectations/tests/struct_containing_forward_declared_struct.rs +++ /dev/null @@ -1,62 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct a { - pub val_a: *mut b, -} -#[test] -fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).val_a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(val_a)) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct b { - pub val_b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_b() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(b)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).val_b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(b), "::", stringify!(val_b)) - ); -} diff --git a/tests/expectations/tests/struct_typedef.rs b/tests/expectations/tests/struct_typedef.rs deleted file mode 100644 index 34c9dbd21e..0000000000 --- a/tests/expectations/tests/struct_typedef.rs +++ /dev/null @@ -1,93 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct typedef_named_struct { - pub has_name: bool, -} -#[test] -fn bindgen_test_layout_typedef_named_struct() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(typedef_named_struct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(typedef_named_struct)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).has_name - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(typedef_named_struct), - "::", - stringify!(has_name) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct _bindgen_ty_1 { - pub no_name: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_bindgen_ty_1>())).no_name as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(no_name) - ) - ); -} -impl Default for _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() - } - } -} -pub type struct_ptr_t = *mut _bindgen_ty_1; -pub type struct_ptr_ptr_t = *mut *mut _bindgen_ty_1; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum typedef_named_enum { - ENUM_HAS_NAME = 1, -} -pub const ENUM_IS_ANON: _bindgen_ty_2 = _bindgen_ty_2::ENUM_IS_ANON; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum _bindgen_ty_2 { - ENUM_IS_ANON = 0, -} -pub type enum_ptr_t = *mut _bindgen_ty_2; -pub type enum_ptr_ptr_t = *mut *mut _bindgen_ty_2; diff --git a/tests/expectations/tests/struct_typedef_ns.rs b/tests/expectations/tests/struct_typedef_ns.rs deleted file mode 100644 index ef91fe49a9..0000000000 --- a/tests/expectations/tests/struct_typedef_ns.rs +++ /dev/null @@ -1,96 +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 { - #[allow(unused_imports)] - use self::super::root; - pub mod whatever { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] - pub struct typedef_struct { - pub foo: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_typedef_struct() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(typedef_struct)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(typedef_struct)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).foo as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(typedef_struct), - "::", - stringify!(foo) - ) - ); - } - #[repr(u32)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub enum typedef_enum { - BAR = 1, - } - } - pub mod _bindgen_mod_id_12 { - #[allow(unused_imports)] - use self::super::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] - pub struct _bindgen_ty_1 { - pub foo: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<_bindgen_ty_1>(), - 4usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<_bindgen_ty_1>(), - 4usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_bindgen_ty_1>())).foo as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(foo) - ) - ); - } - pub type typedef_struct = root::_bindgen_mod_id_12::_bindgen_ty_1; - pub const _bindgen_mod_id_12_BAR: - root::_bindgen_mod_id_12::_bindgen_ty_2 = _bindgen_ty_2::BAR; - #[repr(u32)] - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] - pub enum _bindgen_ty_2 { - BAR = 1, - } - pub use self::super::super::root::_bindgen_mod_id_12::_bindgen_ty_2 as typedef_enum; - } -} diff --git a/tests/expectations/tests/struct_with_anon_struct.rs b/tests/expectations/tests/struct_with_anon_struct.rs deleted file mode 100644 index 0f5d3dac91..0000000000 --- a/tests/expectations/tests/struct_with_anon_struct.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/struct_with_anon_struct_array.rs b/tests/expectations/tests/struct_with_anon_struct_array.rs deleted file mode 100644 index d5a5044832..0000000000 --- a/tests/expectations/tests/struct_with_anon_struct_array.rs +++ /dev/null @@ -1,122 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: [foo__bindgen_ty_1; 2usize], - pub baz: [[[foo__bindgen_ty_2; 4usize]; 3usize]; 2usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_2 { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_2() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_2), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 208usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(baz)) - ); -} diff --git a/tests/expectations/tests/struct_with_anon_struct_pointer.rs b/tests/expectations/tests/struct_with_anon_struct_pointer.rs deleted file mode 100644 index 0ed19f7634..0000000000 --- a/tests/expectations/tests/struct_with_anon_struct_pointer.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: *mut foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/struct_with_anon_union.rs b/tests/expectations/tests/struct_with_anon_union.rs deleted file mode 100644 index 15b8c9e449..0000000000 --- a/tests/expectations/tests/struct_with_anon_union.rs +++ /dev/null @@ -1,91 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_uint, - pub b: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/struct_with_anon_union_1_0.rs b/tests/expectations/tests/struct_with_anon_union_1_0.rs deleted file mode 100644 index b02c44482a..0000000000 --- a/tests/expectations/tests/struct_with_anon_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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(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, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/struct_with_anon_unnamed_struct.rs b/tests/expectations/tests/struct_with_anon_unnamed_struct.rs deleted file mode 100644 index 30751e7d83..0000000000 --- a/tests/expectations/tests/struct_with_anon_unnamed_struct.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); -} diff --git a/tests/expectations/tests/struct_with_anon_unnamed_union.rs b/tests/expectations/tests/struct_with_anon_unnamed_union.rs deleted file mode 100644 index 17a83574e7..0000000000 --- a/tests/expectations/tests/struct_with_anon_unnamed_union.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct foo { - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_uint, - pub b: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs b/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs deleted file mode 100644 index f72abd2b03..0000000000 --- a/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs +++ /dev/null @@ -1,122 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(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, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/struct_with_bitfields.rs b/tests/expectations/tests/struct_with_bitfields.rs deleted file mode 100644 index 2e95726f4c..0000000000 --- a/tests/expectations/tests/struct_with_bitfields.rs +++ /dev/null @@ -1,249 +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 const 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)] -#[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]>, -} -#[test] -fn bindgen_test_layout_bitfield() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(bitfield)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bitfield)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).e as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(bitfield), - "::", - stringify!(e) - ) - ); -} -impl bitfield { - #[inline] - pub fn a(&self) -> ::std::os::raw::c_ushort { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_c(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(6usize, 2u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - a: ::std::os::raw::c_ushort, - b: ::std::os::raw::c_ushort, - c: ::std::os::raw::c_ushort, - d: ::std::os::raw::c_ushort, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u16 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b: u16 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let c: u16 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }); - __bindgen_bitfield_unit.set(6usize, 2u8, { - let d: u16 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); - __bindgen_bitfield_unit - } - #[inline] - pub fn f(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(0usize, 2u8) as u32) - } - } - #[inline] - pub fn set_f(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_2.set(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) - } - } - #[inline] - pub fn set_g(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_2.set(32usize, 32u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_2( - f: ::std::os::raw::c_uint, - g: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 8usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 2u8, { - let f: u32 = unsafe { ::std::mem::transmute(f) }; - f as u64 - }); - __bindgen_bitfield_unit.set(32usize, 32u8, { - let g: u32 = unsafe { ::std::mem::transmute(g) }; - g as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/struct_with_derive_debug.rs b/tests/expectations/tests/struct_with_derive_debug.rs deleted file mode 100644 index 721ba96caf..0000000000 --- a/tests/expectations/tests/struct_with_derive_debug.rs +++ /dev/null @@ -1,143 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct LittleArray { - pub a: [::std::os::raw::c_int; 32usize], -} -#[test] -fn bindgen_test_layout_LittleArray() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(LittleArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(LittleArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(LittleArray), - "::", - stringify!(a) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct BigArray { - pub a: [::std::os::raw::c_int; 33usize], -} -#[test] -fn bindgen_test_layout_BigArray() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(BigArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(BigArray)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(BigArray), - "::", - stringify!(a) - ) - ); -} -impl Default for BigArray { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct WithLittleArray { - pub a: LittleArray, -} -#[test] -fn bindgen_test_layout_WithLittleArray() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(WithLittleArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithLittleArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithLittleArray), - "::", - stringify!(a) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct WithBigArray { - pub a: BigArray, -} -#[test] -fn bindgen_test_layout_WithBigArray() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(WithBigArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray), - "::", - stringify!(a) - ) - ); -} -impl Default for WithBigArray { - 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/tests/expectations/tests/struct_with_large_array.rs b/tests/expectations/tests/struct_with_large_array.rs deleted file mode 100644 index 56179c20f8..0000000000 --- a/tests/expectations/tests/struct_with_large_array.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct S { - pub large_array: [::std::os::raw::c_char; 33usize], -} -#[test] -fn bindgen_test_layout_S() { - assert_eq!( - ::std::mem::size_of::(), - 33usize, - concat!("Size of: ", stringify!(S)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(S)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).large_array as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(S), - "::", - stringify!(large_array) - ) - ); -} -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() - } - } -} -#[repr(C)] -pub struct ST { - pub large_array: [T; 33usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ST { - 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/tests/expectations/tests/struct_with_nesting.rs b/tests/expectations/tests/struct_with_nesting.rs deleted file mode 100644 index 7ced63e6ce..0000000000 --- a/tests/expectations/tests/struct_with_nesting.rs +++ /dev/null @@ -1,199 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct foo { - pub a: ::std::os::raw::c_uint, - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub b: ::std::os::raw::c_uint, - 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, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(c1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c2 - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(c2) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d2 - as *const _ as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d3 - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d3) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d4 - as *const _ as usize - }, - 3usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d4) - ) - ); -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/struct_with_nesting_1_0.rs b/tests/expectations/tests/struct_with_nesting_1_0.rs deleted file mode 100644 index 9f27161a0c..0000000000 --- a/tests/expectations/tests/struct_with_nesting_1_0.rs +++ /dev/null @@ -1,245 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(c1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c2 - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d2 - as *const _ as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d2) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d3 - as *const _ as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(d3) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).d4 - as *const _ as usize - }, - 3usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(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::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/struct_with_packing.rs b/tests/expectations/tests/struct_with_packing.rs deleted file mode 100644 index 14ee36fbaa..0000000000 --- a/tests/expectations/tests/struct_with_packing.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C, packed)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct a { - pub b: ::std::os::raw::c_char, - pub c: ::std::os::raw::c_short, -} -#[test] -fn bindgen_test_layout_a() { - assert_eq!( - ::std::mem::size_of::(), - 3usize, - concat!("Size of: ", stringify!(a)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).c as *const _ as usize }, - 1usize, - concat!("Offset of field: ", stringify!(a), "::", stringify!(c)) - ); -} diff --git a/tests/expectations/tests/struct_with_struct.rs b/tests/expectations/tests/struct_with_struct.rs deleted file mode 100644 index c605c6e2e3..0000000000 --- a/tests/expectations/tests/struct_with_struct.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub x: ::std::os::raw::c_uint, - pub y: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(x) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).y as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(y) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} diff --git a/tests/expectations/tests/struct_with_typedef_template_arg.rs b/tests/expectations/tests/struct_with_typedef_template_arg.rs deleted file mode 100644 index 49afe55906..0000000000 --- a/tests/expectations/tests/struct_with_typedef_template_arg.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Proxy { - pub _address: u8, -} -pub type Proxy_foo = - ::std::option::Option; diff --git a/tests/expectations/tests/template-fun-ty.rs b/tests/expectations/tests/template-fun-ty.rs deleted file mode 100644 index a7132cf04c..0000000000 --- a/tests/expectations/tests/template-fun-ty.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Foo { - pub _address: u8, -} -pub type Foo_FunctionPtr = - ::std::option::Option T>; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct RefPtr { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct RefPtr_Proxy { - pub _address: u8, -} -pub type RefPtr_Proxy_member_function = - ::std::option::Option R>; -pub type Returner = ::std::option::Option T>; diff --git a/tests/expectations/tests/template-param-usage-1.rs b/tests/expectations/tests/template-param-usage-1.rs deleted file mode 100644 index 4fc227c914..0000000000 --- a/tests/expectations/tests/template-param-usage-1.rs +++ /dev/null @@ -1,12 +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 DoesNotUseTemplateParameter { - pub x: ::std::os::raw::c_int, -} diff --git a/tests/expectations/tests/template-param-usage-11.rs b/tests/expectations/tests/template-param-usage-11.rs deleted file mode 100644 index 63a31e234a..0000000000 --- a/tests/expectations/tests/template-param-usage-11.rs +++ /dev/null @@ -1,12 +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 DoesNotUseT { - pub _address: u8, -} diff --git a/tests/expectations/tests/template-param-usage-6.rs b/tests/expectations/tests/template-param-usage-6.rs deleted file mode 100644 index 3c0e515264..0000000000 --- a/tests/expectations/tests/template-param-usage-6.rs +++ /dev/null @@ -1,13 +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 DoesNotUseTemplateParameter { - pub x: ::std::os::raw::c_int, -} -pub type DoesNotUseTemplateParameter_ButAliasDoesUseIt = T; diff --git a/tests/expectations/tests/template-with-var.rs b/tests/expectations/tests/template-with-var.rs deleted file mode 100644 index 0476a256bf..0000000000 --- a/tests/expectations/tests/template-with-var.rs +++ /dev/null @@ -1,12 +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 TemplateWithVar { - pub _address: u8, -} diff --git a/tests/expectations/tests/template.rs b/tests/expectations/tests/template.rs deleted file mode 100644 index 9c48488693..0000000000 --- a/tests/expectations/tests/template.rs +++ /dev/null @@ -1,954 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct Foo { - pub m_member: T, - pub m_member_ptr: *mut T, - pub m_member_arr: [T; 1usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct B { - pub m_member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for B { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_Z3bar3FooIiiE"] - pub fn bar(foo: Foo<::std::os::raw::c_int>); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct mozilla_Foo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct C { - pub mB: B<::std::os::raw::c_uint>, - pub mBConstPtr: B<*const ::std::os::raw::c_int>, - pub mBConstStructPtr: B<*const mozilla_Foo>, - pub mBConstStructPtrArray: B<[*const mozilla_Foo; 1usize]>, - pub mBConst: B<::std::os::raw::c_int>, - pub mBVolatile: B<::std::os::raw::c_int>, - pub mBConstBool: B, - pub mBConstChar: B, - pub mBArray: B<[::std::os::raw::c_int; 1usize]>, - pub mBPtrArray: B<[*mut ::std::os::raw::c_int; 1usize]>, - pub mBArrayPtr: B<*mut [::std::os::raw::c_int; 1usize]>, - pub mBRef: B<*mut ::std::os::raw::c_int>, - pub mBConstRef: B<*const ::std::os::raw::c_int>, - pub mPtrRef: B<*mut *mut ::std::os::raw::c_int>, - pub mArrayRef: B<*mut [::std::os::raw::c_int; 1usize]>, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 96usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mB as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(mB)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstPtr as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstPtr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstStructPtr as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstStructPtr) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstStructPtrArray as *const _ - as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstStructPtrArray) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mBConst as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConst) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBVolatile as *const _ as usize - }, - 36usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBVolatile) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstBool as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstBool) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstChar as *const _ as usize - }, - 42usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstChar) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mBArray as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBArray) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBPtrArray as *const _ as usize - }, - 48usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBPtrArray) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBArrayPtr as *const _ as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBArrayPtr) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mBRef as *const _ as usize }, - 64usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(mBRef)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBConstRef as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mBConstRef) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mPtrRef as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mPtrRef) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mArrayRef as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(C), - "::", - stringify!(mArrayRef) - ) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct D { - pub m_foo: D_MyFoo, -} -pub type D_MyFoo = Foo<::std::os::raw::c_int>; -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct D_U { - pub m_nested_foo: D_MyFoo, - pub m_baz: Z, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for D_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() - } - } -} -impl Default for D { - 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, Hash, PartialEq, Eq)] -pub struct Rooted { - pub prev: *mut T, - pub next: *mut Rooted<*mut ::std::os::raw::c_void>, - pub ptr: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Rooted { - 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, Hash, PartialEq, Eq)] -pub struct RootedContainer { - pub root: Rooted<*mut ::std::os::raw::c_void>, -} -#[test] -fn bindgen_test_layout_RootedContainer() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(RootedContainer)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(RootedContainer)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).root as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(RootedContainer), - "::", - stringify!(root) - ) - ); -} -impl Default for RootedContainer { - 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 type WithDtorIntFwd = WithDtor<::std::os::raw::c_int>; -#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct WithDtor { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for WithDtor { - 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, Hash, PartialEq, Eq)] -pub struct PODButContainsDtor { - pub member: WithDtorIntFwd, -} -#[test] -fn bindgen_test_layout_PODButContainsDtor() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(PODButContainsDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(PODButContainsDtor)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).member as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(PODButContainsDtor), - "::", - stringify!(member) - ) - ); -} -impl Default for PODButContainsDtor { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Opaque { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct POD { - pub opaque_member: u32, -} -#[test] -fn bindgen_test_layout_POD() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(POD)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(POD)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).opaque_member as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(POD), - "::", - stringify!(opaque_member) - ) - ); -} -///
-#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct NestedReplaced { - pub buff: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for NestedReplaced { - 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, Hash, PartialEq, Eq)] -pub struct NestedBase { - pub buff: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for NestedBase { - 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, Hash, PartialEq, Eq)] -pub struct NestedContainer { - pub c: T, - pub nested: NestedReplaced, - pub inc: Incomplete, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for NestedContainer { - 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, Hash, PartialEq, Eq)] -pub struct Incomplete { - pub d: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for Incomplete { - 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, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Untemplated { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Untemplated() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Untemplated)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Untemplated)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Templated { - pub m_untemplated: Untemplated, -} -/// If the replacement doesn't happen at the parse level the container would be -/// copy and the replacement wouldn't, so this wouldn't compile. -/// -///
-#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct ReplacedWithoutDestructor { - pub buff: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ReplacedWithoutDestructor { - 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, Hash, PartialEq, Eq)] -pub struct ShouldNotBeCopiable { - pub m_member: ReplacedWithoutDestructor, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ShouldNotBeCopiable { - 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, Hash, PartialEq, Eq)] -pub struct ShouldNotBeCopiableAsWell { - pub m_member: ReplacedWithoutDestructorFwd, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ShouldNotBeCopiableAsWell { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -/// If the replacement doesn't happen at the parse level the container would be -/// copy and the replacement wouldn't, so this wouldn't compile. -/// -///
-#[repr(C)] -#[derive(Debug, Hash, PartialEq, Eq)] -pub struct ReplacedWithoutDestructorFwd { - pub buff: *mut T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for ReplacedWithoutDestructorFwd { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_Foo_open0_int_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 24usize, - concat!( - "Size of template specialization: ", - stringify!(Foo<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(Foo<::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_unsigned_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(B<::std::os::raw::c_uint>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<::std::os::raw::c_uint>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ptr_const_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*const ::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*const ::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ptr_const_mozilla__Foo_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*const mozilla_Foo>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*const mozilla_Foo>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_array1_ptr_const_mozilla__Foo_close0_instantiation( -) { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<[*const mozilla_Foo; 1usize]>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<[*const mozilla_Foo; 1usize]>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_const_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(B<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_volatile_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(B<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_const_bool_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 1usize, - concat!("Size of template specialization: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::>(), - 1usize, - concat!( - "Alignment of template specialization: ", - stringify!(B) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_const_char16_t_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 2usize, - concat!("Size of template specialization: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::>(), - 2usize, - concat!("Alignment of template specialization: ", stringify!(B)) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_array1_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(B<[::std::os::raw::c_int; 1usize]>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<[::std::os::raw::c_int; 1usize]>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_array1_ptr_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<[*mut ::std::os::raw::c_int; 1usize]>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<[*mut ::std::os::raw::c_int; 1usize]>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ptr_array1_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*mut [::std::os::raw::c_int; 1usize]>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*mut [::std::os::raw::c_int; 1usize]>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ref_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*mut ::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*mut ::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ref_const_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*const ::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*const ::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ref_ptr_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*mut *mut ::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*mut *mut ::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_B_open0_ref_array1_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(B<*mut [::std::os::raw::c_int; 1usize]>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(B<*mut [::std::os::raw::c_int; 1usize]>) - ) - ); -} -#[test] -fn __bindgen_test_layout_Foo_open0_int_int_close0_instantiation_1() { - assert_eq!( - ::std::mem::size_of::>(), - 24usize, - concat!( - "Size of template specialization: ", - stringify!(Foo<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(Foo<::std::os::raw::c_int>) - ) - ); -} -#[test] -fn __bindgen_test_layout_Rooted_open0_ptr_void_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 24usize, - concat!( - "Size of template specialization: ", - stringify!(Rooted<*mut ::std::os::raw::c_void>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(Rooted<*mut ::std::os::raw::c_void>) - ) - ); -} -#[test] -fn __bindgen_test_layout_Rooted_open0_ptr_void_close0_instantiation_1() { - assert_eq!( - ::std::mem::size_of::>(), - 24usize, - concat!( - "Size of template specialization: ", - stringify!(Rooted<*mut ::std::os::raw::c_void>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(Rooted<*mut ::std::os::raw::c_void>) - ) - ); -} -#[test] -fn __bindgen_test_layout_WithDtor_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(WithDtor<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(WithDtor<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/template_alias_basic.rs b/tests/expectations/tests/template_alias_basic.rs deleted file mode 100644 index e06ffadab3..0000000000 --- a/tests/expectations/tests/template_alias_basic.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Wrapped = T; diff --git a/tests/expectations/tests/template_fun.rs b/tests/expectations/tests/template_fun.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/template_fun.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/template_instantiation_with_fn_local_type.rs b/tests/expectations/tests/template_instantiation_with_fn_local_type.rs deleted file mode 100644 index d968e71bae..0000000000 --- a/tests/expectations/tests/template_instantiation_with_fn_local_type.rs +++ /dev/null @@ -1,96 +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, -} -extern "C" { - #[link_name = "\u{1}_Z1fv"] - pub fn f(); -} -#[test] -fn __bindgen_test_layout_Foo_open0_Bar_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Baz { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Baz)) - ); -} -#[test] -fn __bindgen_test_layout_Foo_open0_Boo_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of template specialization: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of template specialization: ", stringify!(Foo)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Boo { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Boo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Boo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Boo)) - ); -} diff --git a/tests/expectations/tests/template_partial_specification.rs b/tests/expectations/tests/template_partial_specification.rs deleted file mode 100644 index 131dbdf39f..0000000000 --- a/tests/expectations/tests/template_partial_specification.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] diff --git a/tests/expectations/tests/template_typedefs.rs b/tests/expectations/tests/template_typedefs.rs deleted file mode 100644 index 3883879d28..0000000000 --- a/tests/expectations/tests/template_typedefs.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type foo = - ::std::option::Option; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -pub type Foo_Char = T; -pub type Foo_FooPtrTypedef = *mut Foo_Char; -pub type Foo_nsCOMArrayEnumFunc = ::std::option::Option< - unsafe extern "C" fn( - aElement: *mut T, - aData: *mut ::std::os::raw::c_void, - ) -> bool, ->; diff --git a/tests/expectations/tests/templatized-bitfield.rs b/tests/expectations/tests/templatized-bitfield.rs deleted file mode 100644 index 5657a65540..0000000000 --- a/tests/expectations/tests/templatized-bitfield.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -/// We don't get a layout for this bitfield, since we don't know what `T` will -/// be, so we cannot allocate bitfield units. The best thing we can do is make -/// the struct opaque. -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct TemplatizedBitfield { - pub _address: u8, -} diff --git a/tests/expectations/tests/test_mixed_header_and_header_contents.rs b/tests/expectations/tests/test_mixed_header_and_header_contents.rs deleted file mode 100644 index c97be9b006..0000000000 --- a/tests/expectations/tests/test_mixed_header_and_header_contents.rs +++ /dev/null @@ -1,111 +0,0 @@ -extern "C" { - pub static mut foo: ::std::option::Option< - unsafe extern "C" fn( - x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, - >; -} -extern "C" { - pub fn bar(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn bar2(b: *const ::std::os::raw::c_char) -> f32; -} -pub type Char = ::std::os::raw::c_char; -pub type SChar = ::std::os::raw::c_schar; -pub type UChar = ::std::os::raw::c_uchar; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Test { - pub ch: ::std::os::raw::c_char, - pub u: ::std::os::raw::c_uchar, - pub d: ::std::os::raw::c_schar, - pub cch: ::std::os::raw::c_char, - pub cu: ::std::os::raw::c_uchar, - pub cd: ::std::os::raw::c_schar, - pub Cch: Char, - pub Cu: UChar, - pub Cd: SChar, - pub Ccch: Char, - pub Ccu: UChar, - pub Ccd: SChar, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ch as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(ch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 1usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(u)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 2usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cch as *const _ as usize }, - 3usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cu as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cd as *const _ as usize }, - 5usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cch as *const _ as usize }, - 6usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cu as *const _ as usize }, - 7usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cd as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccch as *const _ as usize }, - 9usize, - concat!( - "Offset of field: ", - stringify!(Test), - "::", - stringify!(Ccch) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccu as *const _ as usize }, - 10usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccd as *const _ as usize }, - 11usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccd)) - ); -} diff --git a/tests/expectations/tests/test_multiple_header_calls_in_builder.rs b/tests/expectations/tests/test_multiple_header_calls_in_builder.rs deleted file mode 100644 index c77c18342a..0000000000 --- a/tests/expectations/tests/test_multiple_header_calls_in_builder.rs +++ /dev/null @@ -1,105 +0,0 @@ -extern "C" { - pub static mut foo: ::std::option::Option< - unsafe extern "C" fn( - x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, - >; -} -pub type Char = ::std::os::raw::c_char; -pub type SChar = ::std::os::raw::c_schar; -pub type UChar = ::std::os::raw::c_uchar; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Test { - pub ch: ::std::os::raw::c_char, - pub u: ::std::os::raw::c_uchar, - pub d: ::std::os::raw::c_schar, - pub cch: ::std::os::raw::c_char, - pub cu: ::std::os::raw::c_uchar, - pub cd: ::std::os::raw::c_schar, - pub Cch: Char, - pub Cu: UChar, - pub Cd: SChar, - pub Ccch: Char, - pub Ccu: UChar, - pub Ccd: SChar, -} -#[test] -fn bindgen_test_layout_Test() { - assert_eq!( - ::std::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(Test)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Test)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ch as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(ch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, - 1usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(u)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).d as *const _ as usize }, - 2usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(d)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cch as *const _ as usize }, - 3usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cu as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).cd as *const _ as usize }, - 5usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cch as *const _ as usize }, - 6usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cch)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cu as *const _ as usize }, - 7usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Cd as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccch as *const _ as usize }, - 9usize, - concat!( - "Offset of field: ", - stringify!(Test), - "::", - stringify!(Ccch) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccu as *const _ as usize }, - 10usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccu)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).Ccd as *const _ as usize }, - 11usize, - concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccd)) - ); -} diff --git a/tests/expectations/tests/timex.rs b/tests/expectations/tests/timex.rs deleted file mode 100644 index b2a84d8462..0000000000 --- a/tests/expectations/tests/timex.rs +++ /dev/null @@ -1,318 +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 const 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)] -#[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]>, -} -#[test] -fn bindgen_test_layout_timex() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(timex)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(timex)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).tai as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(timex), - "::", - stringify!(tai) - ) - ); -} -impl Default for timex { - 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 timex_named { - pub tai: ::std::os::raw::c_int, - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, -} -#[test] -fn bindgen_test_layout_timex_named() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(timex_named)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(timex_named)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tai as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(timex_named), - "::", - stringify!(tai) - ) - ); -} -impl Default for timex_named { - 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 timex_named { - #[inline] - pub fn a(&self) -> ::std::os::raw::c_int { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 32u8) as u32) - } - } - #[inline] - pub fn set_a(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[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(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) - } - } - #[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(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) - } - } - #[inline] - pub fn set_d(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_e(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_f(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_g(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_h(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_i(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_j(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(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) - } - } - #[inline] - pub fn set_k(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(320usize, 32u8, val as u64) - } - } -} diff --git a/tests/expectations/tests/transform-op.rs b/tests/expectations/tests/transform-op.rs deleted file mode 100644 index 84a9460362..0000000000 --- a/tests/expectations/tests/transform-op.rs +++ /dev/null @@ -1,260 +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::new() - } -} -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 StylePoint { - pub x: T, - pub y: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StylePoint { - 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)] -pub struct StyleFoo { - pub __bindgen_anon_1: __BindgenUnionField, - pub foo: __BindgenUnionField>, - pub bar: __BindgenUnionField>, - pub baz: __BindgenUnionField>, - pub bindgen_union_field: [u8; 0usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -pub const StyleFoo_Tag_Foo: StyleFoo_Tag = 0; -pub const StyleFoo_Tag_Bar: StyleFoo_Tag = 0; -pub const StyleFoo_Tag_Baz: StyleFoo_Tag = 0; -pub const StyleFoo_Tag_Bazz: StyleFoo_Tag = 0; -pub type StyleFoo_Tag = u8; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct StyleFoo_Foo_Body { - pub tag: StyleFoo_Tag, - pub x: i32, - pub y: StylePoint, - pub z: StylePoint, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleFoo_Foo_Body { - 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, Clone)] -pub struct StyleFoo_Bar_Body { - pub tag: StyleFoo_Tag, - pub _0: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleFoo_Bar_Body { - 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, Clone)] -pub struct StyleFoo_Baz_Body { - pub tag: StyleFoo_Tag, - pub _0: StylePoint, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleFoo_Baz_Body { - 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, Clone)] -pub struct StyleFoo__bindgen_ty_1 { - pub tag: StyleFoo_Tag, -} -impl Default for StyleFoo__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, Copy, Clone)] -pub struct StyleBar { - pub tag: StyleBar_Tag, - pub __bindgen_anon_1: StyleBar__bindgen_ty_1, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -pub const StyleBar_Tag_Bar1: StyleBar_Tag = 0; -pub const StyleBar_Tag_Bar2: StyleBar_Tag = 0; -pub const StyleBar_Tag_Bar3: StyleBar_Tag = 0; -pub const StyleBar_Tag_Bar4: StyleBar_Tag = 0; -pub type StyleBar_Tag = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct StyleBar_StyleBar1_Body { - pub x: i32, - pub y: StylePoint, - pub z: StylePoint, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleBar_StyleBar1_Body { - 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, Clone)] -pub struct StyleBar_StyleBar2_Body { - pub _0: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleBar_StyleBar2_Body { - 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, Clone)] -pub struct StyleBar_StyleBar3_Body { - pub _0: StylePoint, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleBar_StyleBar3_Body { - 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)] -pub struct StyleBar__bindgen_ty_1 { - pub bar1: __BindgenUnionField>, - pub bar2: __BindgenUnionField>, - pub bar3: __BindgenUnionField>, - pub bindgen_union_field: [u8; 0usize], - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for StyleBar { - 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_StylePoint_open0_float_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(StylePoint) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(StylePoint) - ) - ); -} -#[test] -fn __bindgen_test_layout_StylePoint_open0_float_close0_instantiation_1() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(StylePoint) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(StylePoint) - ) - ); -} diff --git a/tests/expectations/tests/type-referenced-by-allowlisted-function.rs b/tests/expectations/tests/type-referenced-by-allowlisted-function.rs deleted file mode 100644 index 568f94336b..0000000000 --- a/tests/expectations/tests/type-referenced-by-allowlisted-function.rs +++ /dev/null @@ -1,40 +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 dl_phdr_info { - pub x: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_dl_phdr_info() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(dl_phdr_info)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(dl_phdr_info)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).x as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(dl_phdr_info), - "::", - stringify!(x) - ) - ); -} -extern "C" { - pub fn dl_iterate_phdr(arg1: *mut dl_phdr_info) -> ::std::os::raw::c_int; -} diff --git a/tests/expectations/tests/type_alias_empty.rs b/tests/expectations/tests/type_alias_empty.rs deleted file mode 100644 index cb871a33a2..0000000000 --- a/tests/expectations/tests/type_alias_empty.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type bool_constant = u8; diff --git a/tests/expectations/tests/typedefd-array-as-function-arg.rs b/tests/expectations/tests/typedefd-array-as-function-arg.rs deleted file mode 100644 index 330499b8ab..0000000000 --- a/tests/expectations/tests/typedefd-array-as-function-arg.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type myVector3 = [f32; 3usize]; -extern "C" { - pub fn modifyVectorFunc(v: *mut f32); -} diff --git a/tests/expectations/tests/typeref.rs b/tests/expectations/tests/typeref.rs deleted file mode 100644 index 1c34be7e9b..0000000000 --- a/tests/expectations/tests/typeref.rs +++ /dev/null @@ -1,171 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct mozilla_FragmentOrURL { - pub mIsLocalRef: bool, -} -#[test] -fn bindgen_test_layout_mozilla_FragmentOrURL() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(mozilla_FragmentOrURL)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(mozilla_FragmentOrURL)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsLocalRef - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(mozilla_FragmentOrURL), - "::", - stringify!(mIsLocalRef) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct mozilla_Position { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_mozilla_Position() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(mozilla_Position)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(mozilla_Position)) - ); -} -#[repr(C)] -pub struct mozilla_StyleShapeSource { - pub __bindgen_anon_1: mozilla_StyleShapeSource__bindgen_ty_1, -} -#[repr(C)] -pub union mozilla_StyleShapeSource__bindgen_ty_1 { - pub mPosition: *mut mozilla_Position, - pub mFragmentOrURL: *mut mozilla_FragmentOrURL, -} -impl Default for mozilla_StyleShapeSource__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 mozilla_StyleShapeSource { - 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, Hash, PartialEq, Eq)] -pub struct Bar { - pub mFoo: *mut nsFoo, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mFoo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(mFoo)) - ); -} -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() - } - } -} -#[repr(C)] -pub struct nsFoo { - pub mBar: mozilla_StyleShapeSource, -} -#[test] -fn bindgen_test_layout_nsFoo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsFoo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsFoo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mBar as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsFoo), - "::", - stringify!(mBar) - ) - ); -} -impl Default for nsFoo { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn __bindgen_test_layout_mozilla_StyleShapeSource_open0_int_close0_instantiation( -) { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!( - "Size of template specialization: ", - stringify!(mozilla_StyleShapeSource) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(mozilla_StyleShapeSource) - ) - ); -} diff --git a/tests/expectations/tests/typeref_1_0.rs b/tests/expectations/tests/typeref_1_0.rs deleted file mode 100644 index 2820d9f96c..0000000000 --- a/tests/expectations/tests/typeref_1_0.rs +++ /dev/null @@ -1,211 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(mozilla_FragmentOrURL)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(mozilla_FragmentOrURL)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mIsLocalRef - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(mozilla_FragmentOrURL), - "::", - stringify!(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, - concat!("Size of: ", stringify!(mozilla_Position)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mFoo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsFoo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsFoo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mBar as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsFoo), - "::", - stringify!(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, - concat!( - "Size of template specialization: ", - stringify!(mozilla_StyleShapeSource) - ) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!( - "Alignment of template specialization: ", - stringify!(mozilla_StyleShapeSource) - ) - ); -} diff --git a/tests/expectations/tests/underscore.rs b/tests/expectations/tests/underscore.rs deleted file mode 100644 index 6ef2d8a124..0000000000 --- a/tests/expectations/tests/underscore.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const __: ::std::os::raw::c_int = 10; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct ptr_t { - pub __: [::std::os::raw::c_uchar; 8usize], -} -#[test] -fn bindgen_test_layout_ptr_t() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(ptr_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ptr_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__ as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ptr_t), "::", stringify!(__)) - ); -} diff --git a/tests/expectations/tests/union-align.rs b/tests/expectations/tests/union-align.rs deleted file mode 100644 index 8612764186..0000000000 --- a/tests/expectations/tests/union-align.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub union Bar { - pub foo: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Bar), "::", stringify!(foo)) - ); -} -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)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub union Baz { - pub bar: Bar, -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(Baz)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(Baz), "::", stringify!(bar)) - ); -} -impl Default for Baz { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/tests/expectations/tests/union-in-ns.rs b/tests/expectations/tests/union-in-ns.rs deleted file mode 100644 index b52c6c3600..0000000000 --- a/tests/expectations/tests/union-in-ns.rs +++ /dev/null @@ -1,49 +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 { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Copy, Clone)] - pub union bar { - pub baz: ::std::os::raw::c_int, - } - #[test] - fn bindgen_test_layout_bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(baz) - ) - ); - } - 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/tests/expectations/tests/union-in-ns_1_0.rs b/tests/expectations/tests/union-in-ns_1_0.rs deleted file mode 100644 index c210c38c74..0000000000 --- a/tests/expectations/tests/union-in-ns_1_0.rs +++ /dev/null @@ -1,92 +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::new() - } - } - 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(bar), - "::", - stringify!(baz) - ) - ); - } - impl Clone for bar { - fn clone(&self) -> Self { - *self - } - } -} diff --git a/tests/expectations/tests/union_bitfield.rs b/tests/expectations/tests/union_bitfield.rs deleted file mode 100644 index 9e07a1dfcd..0000000000 --- a/tests/expectations/tests/union_bitfield.rs +++ /dev/null @@ -1,223 +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 const 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)] -#[repr(align(4))] -#[derive(Copy, Clone)] -pub union U4 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, -} -#[test] -fn bindgen_test_layout_U4() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(U4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(U4)) - ); -} -impl Default for U4 { - 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 U4 { - #[inline] - pub fn derp(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.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.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)] -#[repr(align(4))] -#[derive(Copy, Clone)] -pub union B { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(B)) - ); -} -impl Default for B { - 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 B { - #[inline] - pub fn foo(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.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.set(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) - } - } - #[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) - } - } - #[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 - } -} diff --git a/tests/expectations/tests/union_bitfield_1_0.rs b/tests/expectations/tests/union_bitfield_1_0.rs deleted file mode 100644 index 2227746849..0000000000 --- a/tests/expectations/tests/union_bitfield_1_0.rs +++ /dev/null @@ -1,298 +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::new() - } -} -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, - concat!("Size of: ", stringify!(U4)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(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, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(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, - concat!("Size of: ", stringify!(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/tests/expectations/tests/union_dtor.rs b/tests/expectations/tests/union_dtor.rs deleted file mode 100644 index 94ad3fd873..0000000000 --- a/tests/expectations/tests/union_dtor.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub union UnionWithDtor { - pub mFoo: ::std::os::raw::c_int, - pub mBar: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_UnionWithDtor() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(UnionWithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(UnionWithDtor)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFoo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(UnionWithDtor), - "::", - stringify!(mFoo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(UnionWithDtor), - "::", - stringify!(mBar) - ) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN13UnionWithDtorD1Ev"] - pub fn UnionWithDtor_UnionWithDtor_destructor(this: *mut UnionWithDtor); -} -impl Default for UnionWithDtor { - 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 UnionWithDtor { - #[inline] - pub unsafe fn destruct(&mut self) { - UnionWithDtor_UnionWithDtor_destructor(self) - } -} diff --git a/tests/expectations/tests/union_dtor_1_0.rs b/tests/expectations/tests/union_dtor_1_0.rs deleted file mode 100644 index a59f99fc6c..0000000000 --- a/tests/expectations/tests/union_dtor_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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(UnionWithDtor)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(UnionWithDtor)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFoo as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(UnionWithDtor), - "::", - stringify!(mFoo) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mBar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(UnionWithDtor), - "::", - stringify!(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/tests/expectations/tests/union_fields.rs b/tests/expectations/tests/union_fields.rs deleted file mode 100644 index 6cd0d56cdb..0000000000 --- a/tests/expectations/tests/union_fields.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union nsStyleUnion { - pub mInt: ::std::os::raw::c_int, - pub mFloat: f32, - pub mPointer: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_nsStyleUnion() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsStyleUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsStyleUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mInt as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mInt) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFloat as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mFloat) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mPointer as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mPointer) - ) - ); -} -impl Default for nsStyleUnion { - 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/tests/expectations/tests/union_fields_1_0.rs b/tests/expectations/tests/union_fields_1_0.rs deleted file mode 100644 index 36972b6b8f..0000000000 --- a/tests/expectations/tests/union_fields_1_0.rs +++ /dev/null @@ -1,113 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsStyleUnion)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsStyleUnion)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mInt as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mInt) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFloat as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mFloat) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mPointer as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(nsStyleUnion), - "::", - stringify!(mPointer) - ) - ); -} -impl Clone for nsStyleUnion { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_template_1_0.rs b/tests/expectations/tests/union_template_1_0.rs deleted file mode 100644 index 487579f7e5..0000000000 --- a/tests/expectations/tests/union_template_1_0.rs +++ /dev/null @@ -1,78 +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::new() - } -} -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 NastyStruct { - pub mIsSome: bool, - pub mStorage: NastyStruct__bindgen_ty_1, - pub __bindgen_anon_1: NastyStruct__bindgen_ty_2, -} -#[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, -} diff --git a/tests/expectations/tests/union_with_anon_struct.rs b/tests/expectations/tests/union_with_anon_struct.rs deleted file mode 100644 index afb735043d..0000000000 --- a/tests/expectations/tests/union_with_anon_struct.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/union_with_anon_struct_1_0.rs b/tests/expectations/tests/union_with_anon_struct_1_0.rs deleted file mode 100644 index 09dcfa1b08..0000000000 --- a/tests/expectations/tests/union_with_anon_struct_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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(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::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/tests/expectations/tests/union_with_anon_struct_bitfield.rs deleted file mode 100644 index 09ed515f99..0000000000 --- a/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ /dev/null @@ -1,191 +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 const 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)] -#[derive(Copy, Clone)] -pub union foo { - pub a: ::std::os::raw::c_int, - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[repr(align(4))] -#[derive(Debug, Default, Copy, Clone, 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, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs b/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs deleted file mode 100644 index 43736b0311..0000000000 --- a/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs +++ /dev/null @@ -1,236 +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::new() - } -} -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]>, - pub __bindgen_align: [u32; 0usize], -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_with_anon_union.rs b/tests/expectations/tests/union_with_anon_union.rs deleted file mode 100644 index a24962c4a6..0000000000 --- a/tests/expectations/tests/union_with_anon_union.rs +++ /dev/null @@ -1,91 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_uint, - pub b: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/union_with_anon_union_1_0.rs b/tests/expectations/tests/union_with_anon_union_1_0.rs deleted file mode 100644 index f892c45f8b..0000000000 --- a/tests/expectations/tests/union_with_anon_union_1_0.rs +++ /dev/null @@ -1,128 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(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, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_with_anon_unnamed_struct.rs b/tests/expectations/tests/union_with_anon_unnamed_struct.rs deleted file mode 100644 index 94380d1a54..0000000000 --- a/tests/expectations/tests/union_with_anon_unnamed_struct.rs +++ /dev/null @@ -1,118 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union pixel { - pub rgba: ::std::os::raw::c_uint, - pub __bindgen_anon_1: pixel__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, 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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pixel__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(pixel__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).r as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(r) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).g as *const _ - as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(g) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 3usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(a) - ) - ); -} -#[test] -fn bindgen_test_layout_pixel() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pixel)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(pixel)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rgba as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(pixel), - "::", - stringify!(rgba) - ) - ); -} -impl Default for pixel { - 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/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs b/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs deleted file mode 100644 index cbdac700fb..0000000000 --- a/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs +++ /dev/null @@ -1,163 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pixel__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(pixel__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).r as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(r) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).g as *const _ - as usize - }, - 1usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(g) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ - as usize - }, - 2usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ - as usize - }, - 3usize, - concat!( - "Offset of field: ", - stringify!(pixel__bindgen_ty_1), - "::", - stringify!(a) - ) - ); -} -impl Clone for pixel__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_pixel() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pixel)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(pixel)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rgba as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(pixel), - "::", - stringify!(rgba) - ) - ); -} -impl Clone for pixel { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_with_anon_unnamed_union.rs b/tests/expectations/tests/union_with_anon_unnamed_union.rs deleted file mode 100644 index 2004ff4cef..0000000000 --- a/tests/expectations/tests/union_with_anon_unnamed_union.rs +++ /dev/null @@ -1,92 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo { - pub a: ::std::os::raw::c_uint, - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1 { - pub b: ::std::os::raw::c_ushort, - pub c: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(c) - ) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs b/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs deleted file mode 100644 index 910f5885c0..0000000000 --- a/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs +++ /dev/null @@ -1,129 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1), - "::", - stringify!(c) - ) - ); -} -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, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/union_with_big_member.rs b/tests/expectations/tests/union_with_big_member.rs deleted file mode 100644 index 3f9294dd05..0000000000 --- a/tests/expectations/tests/union_with_big_member.rs +++ /dev/null @@ -1,163 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union WithBigArray { - pub a: ::std::os::raw::c_int, - pub b: [::std::os::raw::c_int; 33usize], -} -#[test] -fn bindgen_test_layout_WithBigArray() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(WithBigArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray), - "::", - stringify!(b) - ) - ); -} -impl Default for WithBigArray { - 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(Copy, Clone)] -pub union WithBigArray2 { - pub a: ::std::os::raw::c_int, - pub b: [::std::os::raw::c_char; 33usize], -} -#[test] -fn bindgen_test_layout_WithBigArray2() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(WithBigArray2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigArray2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray2), - "::", - stringify!(b) - ) - ); -} -impl Default for WithBigArray2 { - 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(Copy, Clone)] -pub union WithBigMember { - pub a: ::std::os::raw::c_int, - pub b: WithBigArray, -} -#[test] -fn bindgen_test_layout_WithBigMember() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(WithBigMember)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigMember)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigMember), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigMember), - "::", - stringify!(b) - ) - ); -} -impl Default for WithBigMember { - 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/tests/expectations/tests/union_with_big_member_1_0.rs b/tests/expectations/tests/union_with_big_member_1_0.rs deleted file mode 100644 index 541c9d4c77..0000000000 --- a/tests/expectations/tests/union_with_big_member_1_0.rs +++ /dev/null @@ -1,215 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(WithBigArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(WithBigArray2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigArray2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray2), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigArray2), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, - concat!("Size of: ", stringify!(WithBigMember)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(WithBigMember)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).a as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigMember), - "::", - stringify!(a) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(WithBigMember), - "::", - stringify!(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/tests/expectations/tests/union_with_nesting.rs b/tests/expectations/tests/union_with_nesting.rs deleted file mode 100644 index 54a3179b41..0000000000 --- a/tests/expectations/tests/union_with_nesting.rs +++ /dev/null @@ -1,176 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo { - pub a: ::std::os::raw::c_uint, - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Copy, Clone)] -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(Copy, Clone)] -pub union foo__bindgen_ty_1__bindgen_ty_1 { - pub b1: ::std::os::raw::c_ushort, - pub b2: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(b1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b2 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(b2) - ) - ); -} -impl Default for foo__bindgen_ty_1__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() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union foo__bindgen_ty_1__bindgen_ty_2 { - 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_2() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(c1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c2 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(c2) - ) - ); -} -impl Default for foo__bindgen_ty_1__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); -} -impl Default for foo__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() - } - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -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() - } - } -} diff --git a/tests/expectations/tests/union_with_nesting_1_0.rs b/tests/expectations/tests/union_with_nesting_1_0.rs deleted file mode 100644 index 3f105c39e8..0000000000 --- a/tests/expectations/tests/union_with_nesting_1_0.rs +++ /dev/null @@ -1,206 +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::new() - } -} -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() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(b1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).b2 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(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() { - assert_eq!( - ::std::mem::size_of::(), - 2usize, - concat!("Size of: ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1__bindgen_ty_2)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(c1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).c2 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(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, - concat!("Size of: ", stringify!(foo__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(foo__bindgen_ty_1)) - ); -} -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, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/unknown_attr.rs b/tests/expectations/tests/unknown_attr.rs deleted file mode 100644 index 8dbda00d71..0000000000 --- a/tests/expectations/tests/unknown_attr.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[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 __clang_max_align_nonce2: ::std::os::raw::c_longlong, -} -#[test] -fn bindgen_test_layout_max_align_t() { - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(max_align_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(max_align_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).__clang_max_align_nonce1 - as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(max_align_t), - "::", - stringify!(__clang_max_align_nonce1) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).__clang_max_align_nonce2 - as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(max_align_t), - "::", - stringify!(__clang_max_align_nonce2) - ) - ); -} diff --git a/tests/expectations/tests/use-core.rs b/tests/expectations/tests/use-core.rs deleted file mode 100644 index d919b6e745..0000000000 --- a/tests/expectations/tests/use-core.rs +++ /dev/null @@ -1,110 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern crate core; - -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct foo { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, - pub bar: *mut ::core::ffi::c_void, -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).b as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).bar as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar)) - ); -} -impl Default for foo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union _bindgen_ty_1 { - pub bar: ::std::os::raw::c_int, - pub baz: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - assert_eq!( - ::core::mem::size_of::<_bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::core::mem::align_of::<_bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::<_bindgen_ty_1>())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(bar) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::<_bindgen_ty_1>())).baz as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(baz) - ) - ); -} -impl Default for _bindgen_ty_1 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - pub static mut bazz: _bindgen_ty_1; -} -pub type fooFunction = - ::core::option::Option; diff --git a/tests/expectations/tests/use-core_1_0.rs b/tests/expectations/tests/use-core_1_0.rs deleted file mode 100644 index 61ddfc42cb..0000000000 --- a/tests/expectations/tests/use-core_1_0.rs +++ /dev/null @@ -1,155 +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::new() - } -} -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() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).a as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(a)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).b as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).bar as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(foo), "::", stringify!(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() { - assert_eq!( - ::core::mem::size_of::<_bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - ::core::mem::align_of::<_bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(_bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::<_bindgen_ty_1>())).bar as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(bar) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::<_bindgen_ty_1>())).baz as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_bindgen_ty_1), - "::", - stringify!(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; diff --git a/tests/expectations/tests/var-tracing.rs b/tests/expectations/tests/var-tracing.rs deleted file mode 100644 index 2931f9121c..0000000000 --- a/tests/expectations/tests/var-tracing.rs +++ /dev/null @@ -1,69 +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 Bar { - pub m_baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Bar)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).m_baz as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Bar), - "::", - stringify!(m_baz) - ) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3BarC1Ei"] - pub fn Bar_Bar(this: *mut Bar, baz: ::std::os::raw::c_int); -} -impl Bar { - #[inline] - pub unsafe fn new(baz: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Bar_Bar(__bindgen_tmp.as_mut_ptr(), baz); - __bindgen_tmp.assume_init() - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Baz { - pub _address: u8, -} -extern "C" { - #[link_name = "\u{1}_ZN3Baz3FOOE"] - pub static mut Baz_FOO: [Bar; 0usize]; -} -#[test] -fn bindgen_test_layout_Baz() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Baz)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Baz)) - ); -} diff --git a/tests/expectations/tests/variadic-method.rs b/tests/expectations/tests/variadic-method.rs deleted file mode 100644 index be93dda70b..0000000000 --- a/tests/expectations/tests/variadic-method.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - #[link_name = "\u{1}_Z3fooPKcz"] - pub fn foo(fmt: *const ::std::os::raw::c_char, ...); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Bar { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Bar() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Bar)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Bar)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3Bar3fooEPKcz"] - pub fn Bar_foo(this: *mut Bar, fmt: *const ::std::os::raw::c_char, ...); -} diff --git a/tests/expectations/tests/variadic_template_function.rs b/tests/expectations/tests/variadic_template_function.rs deleted file mode 100644 index 8f67136ac8..0000000000 --- a/tests/expectations/tests/variadic_template_function.rs +++ /dev/null @@ -1,12 +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 VariadicFunctionObject { - pub _address: u8, -} diff --git a/tests/expectations/tests/vector.rs b/tests/expectations/tests/vector.rs deleted file mode 100644 index 04f4de714b..0000000000 --- a/tests/expectations/tests/vector.rs +++ /dev/null @@ -1,42 +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 mMember: [::std::os::raw::c_longlong; 1usize], -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(foo)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).mMember as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(foo), - "::", - stringify!(mMember) - ) - ); -} -pub type __m128 = [f32; 4usize]; -pub type __m128d = [f64; 2usize]; -pub type __m128i = [::std::os::raw::c_longlong; 2usize]; -extern "C" { - #[link_name = "\u{1}_Z3fooDv2_xDv2_d"] - pub fn foo(arg1: __m128i, arg2: __m128d) -> __m128; -} diff --git a/tests/expectations/tests/virtual_dtor.rs b/tests/expectations/tests/virtual_dtor.rs deleted file mode 100644 index c3c66e91d8..0000000000 --- a/tests/expectations/tests/virtual_dtor.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct nsSlots__bindgen_vtable(::std::os::raw::c_void); -#[repr(C)] -#[derive(Debug)] -pub struct nsSlots { - pub vtable_: *const nsSlots__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_nsSlots() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(nsSlots)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(nsSlots)) - ); -} -impl Default for nsSlots { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_ZN7nsSlotsD1Ev"] - pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots); -} diff --git a/tests/expectations/tests/virtual_inheritance.rs b/tests/expectations/tests/virtual_inheritance.rs deleted file mode 100644 index eac6aa665e..0000000000 --- a/tests/expectations/tests/virtual_inheritance.rs +++ /dev/null @@ -1,129 +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 A { - pub foo: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A() { - assert_eq!( - ::std::mem::size_of::
(), - 4usize, - concat!("Size of: ", stringify!(A)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(A)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).foo as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(A), "::", stringify!(foo)) - ); -} -#[repr(C)] -pub struct B__bindgen_vtable(::std::os::raw::c_void); -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct B { - pub vtable_: *const B__bindgen_vtable, - pub bar: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(B)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(B)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).bar as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(B), "::", stringify!(bar)) - ); -} -impl Default for B { - 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 C__bindgen_vtable(::std::os::raw::c_void); -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct C { - pub vtable_: *const C__bindgen_vtable, - pub baz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(C)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).baz as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(C), "::", stringify!(baz)) - ); -} -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() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct D { - pub _base: C, - pub _base_1: B, - pub bazz: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_D() { - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(D)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(D)) - ); -} -impl Default for D { - 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/tests/expectations/tests/virtual_interface.rs b/tests/expectations/tests/virtual_interface.rs deleted file mode 100644 index be94f23205..0000000000 --- a/tests/expectations/tests/virtual_interface.rs +++ /dev/null @@ -1,128 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct PureVirtualIFace__bindgen_vtable { - pub PureVirtualIFace_Foo: unsafe extern "C" fn(this: *mut PureVirtualIFace), - pub PureVirtualIFace_Bar: unsafe extern "C" fn( - this: *mut PureVirtualIFace, - arg1: ::std::os::raw::c_uint, - ), -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct PureVirtualIFace { - pub vtable_: *const PureVirtualIFace__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_PureVirtualIFace() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(PureVirtualIFace)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(PureVirtualIFace)) - ); -} -impl Default for PureVirtualIFace { - 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 AnotherInterface__bindgen_vtable { - pub AnotherInterface_Baz: unsafe extern "C" fn(this: *mut AnotherInterface), -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct AnotherInterface { - pub vtable_: *const AnotherInterface__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_AnotherInterface() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(AnotherInterface)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(AnotherInterface)) - ); -} -impl Default for AnotherInterface { - 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 Implementation { - pub _base: PureVirtualIFace, -} -#[test] -fn bindgen_test_layout_Implementation() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Implementation)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Implementation)) - ); -} -impl Default for Implementation { - 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 DoubleImpl { - pub _base: PureVirtualIFace, - pub _base_1: AnotherInterface, -} -#[test] -fn bindgen_test_layout_DoubleImpl() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(DoubleImpl)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(DoubleImpl)) - ); -} -impl Default for DoubleImpl { - 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/tests/expectations/tests/virtual_overloaded.rs b/tests/expectations/tests/virtual_overloaded.rs deleted file mode 100644 index c117d9ef6c..0000000000 --- a/tests/expectations/tests/virtual_overloaded.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct C__bindgen_vtable { - pub C_do_thing: - unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_char), - pub C_do_thing1: - unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_int), -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct C { - pub vtable_: *const C__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_C() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(C)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(C)) - ); -} -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() - } - } -} -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" { - #[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/tests/expectations/tests/vtable_recursive_sig.rs b/tests/expectations/tests/vtable_recursive_sig.rs deleted file mode 100644 index 74e1dc7914..0000000000 --- a/tests/expectations/tests/vtable_recursive_sig.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -pub struct Base__bindgen_vtable { - pub Base_AsDerived: unsafe extern "C" fn(this: *mut Base) -> *mut Derived, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Base { - pub vtable_: *const Base__bindgen_vtable, -} -#[test] -fn bindgen_test_layout_Base() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Base)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Base)) - ); -} -impl Default for Base { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -extern "C" { - #[link_name = "\u{1}_ZN4Base9AsDerivedEv"] - pub fn Base_AsDerived(this: *mut ::std::os::raw::c_void) -> *mut Derived; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Derived { - pub _base: Base, -} -#[test] -fn bindgen_test_layout_Derived() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(Derived)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(Derived)) - ); -} -impl Default for Derived { - 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/tests/expectations/tests/wasm-constructor-returns.rs b/tests/expectations/tests/wasm-constructor-returns.rs deleted file mode 100644 index 6d15c51f9d..0000000000 --- a/tests/expectations/tests/wasm-constructor-returns.rs +++ /dev/null @@ -1,40 +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, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "C" { - #[link_name = "\u{1}_ZN3FooC1Ei"] - pub fn Foo_Foo( - this: *mut Foo, - var: ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_void; -} -impl Foo { - #[inline] - pub unsafe fn new(var: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - Foo_Foo(__bindgen_tmp.as_mut_ptr(), var); - __bindgen_tmp.assume_init() - } -} diff --git a/tests/expectations/tests/wasm-import-module.rs b/tests/expectations/tests/wasm-import-module.rs deleted file mode 100644 index e334a7b734..0000000000 --- a/tests/expectations/tests/wasm-import-module.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[link(wasm_import_module = "test-module")] -extern "C" { - pub fn test_function(); -} diff --git a/tests/expectations/tests/weird_bitfields.rs b/tests/expectations/tests/weird_bitfields.rs deleted file mode 100644 index c4dfa55ad9..0000000000 --- a/tests/expectations/tests/weird_bitfields.rs +++ /dev/null @@ -1,442 +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 const 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(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum nsStyleSVGOpacitySource { - eStyleSVGOpacitySource_Normal = 0, - eStyleSVGOpacitySource_ContextFillOpacity = 1, - eStyleSVGOpacitySource_ContextStrokeOpacity = 2, -} -#[repr(C)] -#[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, - pub mColorInterpolationFilters: ::std::os::raw::c_uchar, - pub mFillRule: ::std::os::raw::c_uchar, - pub mImageRendering: ::std::os::raw::c_uchar, - pub mPaintOrder: ::std::os::raw::c_uchar, - pub mShapeRendering: ::std::os::raw::c_uchar, - pub mStrokeLinecap: ::std::os::raw::c_uchar, - 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], -} -#[test] -fn bindgen_test_layout_Weird() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(Weird)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Weird)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mStrokeDasharrayLength as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mStrokeDasharrayLength) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mClipRule as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mClipRule) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mColorInterpolation as *const _ - as usize - }, - 9usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mColorInterpolation) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mColorInterpolationFilters - as *const _ as usize - }, - 10usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mColorInterpolationFilters) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mFillRule as *const _ as usize - }, - 11usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mFillRule) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mImageRendering as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mImageRendering) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mPaintOrder as *const _ as usize - }, - 13usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mPaintOrder) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mShapeRendering as *const _ - as usize - }, - 14usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mShapeRendering) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mStrokeLinecap as *const _ - as usize - }, - 15usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mStrokeLinecap) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mStrokeLinejoin as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mStrokeLinejoin) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mTextAnchor as *const _ as usize - }, - 17usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mTextAnchor) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).mTextRendering as *const _ - as usize - }, - 18usize, - concat!( - "Offset of field: ", - stringify!(Weird), - "::", - stringify!(mTextRendering) - ) - ); -} -impl Default for Weird { - 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 Weird { - #[inline] - pub fn bitTest(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) - } - } - #[inline] - pub fn set_bitTest(&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 fn bitTest2(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(16usize, 15u8) as u32) - } - } - #[inline] - pub fn set_bitTest2(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(16usize, 15u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - bitTest: ::std::os::raw::c_uint, - bitTest2: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 16u8, { - let bitTest: u32 = unsafe { ::std::mem::transmute(bitTest) }; - bitTest as u64 - }); - __bindgen_bitfield_unit.set(16usize, 15u8, { - let bitTest2: u32 = unsafe { ::std::mem::transmute(bitTest2) }; - bitTest2 as u64 - }); - __bindgen_bitfield_unit - } - #[inline] - pub fn mFillOpacitySource(&self) -> nsStyleSVGOpacitySource { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(0usize, 3u8) as u32) - } - } - #[inline] - pub fn set_mFillOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_2.set(0usize, 3u8, val as u64) - } - } - #[inline] - pub fn mStrokeOpacitySource(&self) -> nsStyleSVGOpacitySource { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(3usize, 3u8) as u32) - } - } - #[inline] - pub fn set_mStrokeOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_2.set(3usize, 3u8, val as u64) - } - } - #[inline] - pub fn mStrokeDasharrayFromObject(&self) -> bool { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(6usize, 1u8) as u8) - } - } - #[inline] - pub fn set_mStrokeDasharrayFromObject(&mut self, val: bool) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(6usize, 1u8, val as u64) - } - } - #[inline] - pub fn mStrokeDashoffsetFromObject(&self) -> bool { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(7usize, 1u8) as u8) - } - } - #[inline] - pub fn set_mStrokeDashoffsetFromObject(&mut self, val: bool) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(7usize, 1u8, val as u64) - } - } - #[inline] - pub fn mStrokeWidthFromObject(&self) -> bool { - unsafe { - ::std::mem::transmute(self._bitfield_2.get(8usize, 1u8) as u8) - } - } - #[inline] - pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_2.set(8usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_2( - mFillOpacitySource: nsStyleSVGOpacitySource, - mStrokeOpacitySource: nsStyleSVGOpacitySource, - mStrokeDasharrayFromObject: bool, - mStrokeDashoffsetFromObject: bool, - mStrokeWidthFromObject: bool, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let mFillOpacitySource: u32 = - unsafe { ::std::mem::transmute(mFillOpacitySource) }; - mFillOpacitySource as u64 - }); - __bindgen_bitfield_unit.set(3usize, 3u8, { - let mStrokeOpacitySource: u32 = - unsafe { ::std::mem::transmute(mStrokeOpacitySource) }; - mStrokeOpacitySource as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let mStrokeDasharrayFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeDasharrayFromObject) }; - mStrokeDasharrayFromObject as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let mStrokeDashoffsetFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeDashoffsetFromObject) }; - mStrokeDashoffsetFromObject as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let mStrokeWidthFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeWidthFromObject) }; - mStrokeWidthFromObject as u64 - }); - __bindgen_bitfield_unit - } -} diff --git a/tests/expectations/tests/what_is_going_on.rs b/tests/expectations/tests/what_is_going_on.rs deleted file mode 100644 index b4f42791db..0000000000 --- a/tests/expectations/tests/what_is_going_on.rs +++ /dev/null @@ -1,43 +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 UnknownUnits { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_UnknownUnits() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(UnknownUnits)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(UnknownUnits)) - ); -} -pub type Float = f32; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct PointTyped { - pub x: F, - pub y: F, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, -} -impl Default for PointTyped { - 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 type IntPoint = PointTyped; diff --git a/tests/expectations/tests/win32-thiscall_1_0.rs b/tests/expectations/tests/win32-thiscall_1_0.rs deleted file mode 100644 index 502e12fe44..0000000000 --- a/tests/expectations/tests/win32-thiscall_1_0.rs +++ /dev/null @@ -1,30 +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, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -impl Clone for Foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/tests/expectations/tests/win32-thiscall_nightly.rs b/tests/expectations/tests/win32-thiscall_nightly.rs deleted file mode 100644 index 92bb13cc61..0000000000 --- a/tests/expectations/tests/win32-thiscall_nightly.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![cfg(feature = "nightly")] -#![feature(abi_thiscall)] - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - concat!("Size of: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(Foo)) - ); -} -extern "thiscall" { - #[link_name = "\u{1}?test@Foo@@QAEXXZ"] - pub fn Foo_test(this: *mut Foo); -} -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/tests/expectations/tests/with_array_pointers_arguments.rs b/tests/expectations/tests/with_array_pointers_arguments.rs deleted file mode 100644 index 2a7d18025d..0000000000 --- a/tests/expectations/tests/with_array_pointers_arguments.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn test_fn( - a: f32, - arr: *mut [::std::os::raw::c_int; 20usize], - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn test_fn2( - arr: *const [f32; 20usize], - 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; -extern "C" { - pub fn bar(a: *mut defArr); -} diff --git a/tests/expectations/tests/without_array_pointers_arguments.rs b/tests/expectations/tests/without_array_pointers_arguments.rs deleted file mode 100644 index c4acdb3e91..0000000000 --- a/tests/expectations/tests/without_array_pointers_arguments.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -extern "C" { - pub fn test_fn( - a: f32, - arr: *mut ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; -} -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; -extern "C" { - pub fn bar(a: *mut ::std::os::raw::c_char); -} diff --git a/tests/expectations/tests/zero-size-array-align.rs b/tests/expectations/tests/zero-size-array-align.rs deleted file mode 100644 index 92b6798fb2..0000000000 --- a/tests/expectations/tests/zero-size-array-align.rs +++ /dev/null @@ -1,93 +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 const 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)] -#[derive(Debug, Default)] -pub struct dm_deps { - pub count: ::std::os::raw::c_uint, - pub filler: ::std::os::raw::c_uint, - pub device: __IncompleteArrayField<::std::os::raw::c_ulonglong>, -} -#[test] -fn bindgen_test_layout_dm_deps() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(dm_deps)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(dm_deps)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).count as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(dm_deps), - "::", - stringify!(count) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).filler as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(dm_deps), - "::", - stringify!(filler) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).device as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(dm_deps), - "::", - stringify!(device) - ) - ); -} diff --git a/tests/expectations/tests/zero-sized-array.rs b/tests/expectations/tests/zero-sized-array.rs deleted file mode 100644 index 347c22649d..0000000000 --- a/tests/expectations/tests/zero-sized-array.rs +++ /dev/null @@ -1,158 +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 const 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") - } -} -/// Bizarrely enough, this should *not* get an `_address` field. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ZeroSizedArray { - pub arr: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_ZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ZeroSizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).arr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ZeroSizedArray), - "::", - stringify!(arr) - ) - ); -} -/// And nor should this get an `_address` field. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ContainsZeroSizedArray { - pub zsa: ZeroSizedArray, -} -#[test] -fn bindgen_test_layout_ContainsZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ContainsZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsZeroSizedArray)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).zsa as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(ContainsZeroSizedArray), - "::", - stringify!(zsa) - ) - ); -} -/// Inheriting from ZeroSizedArray shouldn't cause an `_address` to be inserted -/// either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct InheritsZeroSizedArray { - pub _base: ZeroSizedArray, -} -#[test] -fn bindgen_test_layout_InheritsZeroSizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(InheritsZeroSizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(InheritsZeroSizedArray)) - ); -} -/// And this should not get an `_address` field either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct DynamicallySizedArray { - pub arr: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_DynamicallySizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(DynamicallySizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(DynamicallySizedArray)) - ); -} -/// No `_address` field here either. -#[repr(C)] -#[derive(Debug, Default)] -pub struct ContainsDynamicallySizedArray { - pub dsa: DynamicallySizedArray, -} -#[test] -fn bindgen_test_layout_ContainsDynamicallySizedArray() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(ContainsDynamicallySizedArray)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(ContainsDynamicallySizedArray)) - ); -} diff --git a/tests/headers/16-byte-alignment_1_0.h b/tests/headers/16-byte-alignment_1_0.h deleted file mode 100644 index 8a9fd4910e..0000000000 --- a/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/tests/headers/anon_struct_in_union_1_0.h b/tests/headers/anon_struct_in_union_1_0.h deleted file mode 100644 index 6b59723a3c..0000000000 --- a/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/tests/headers/anon_union_1_0.hpp b/tests/headers/anon_union_1_0.hpp deleted file mode 100644 index 3d9ae3dde9..0000000000 --- a/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/tests/headers/attribute_warn_unused_result.hpp b/tests/headers/attribute_warn_unused_result.hpp deleted file mode 100644 index 26fda0910c..0000000000 --- a/tests/headers/attribute_warn_unused_result.hpp +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --rust-target 1.27 --enable-function-attribute-detection - -class Foo { -public: - __attribute__((warn_unused_result)) - int foo(int); -}; - -__attribute__((warn_unused_result)) -int foo(int); diff --git a/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp b/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp deleted file mode 100644 index 2155030711..0000000000 --- a/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --rust-target 1.27 - -class Foo { -public: - __attribute__((warn_unused_result)) - int foo(int); -}; - -__attribute__((warn_unused_result)) -int foo(int); diff --git a/tests/headers/bindgen-union-inside-namespace.hpp b/tests/headers/bindgen-union-inside-namespace.hpp deleted file mode 100644 index 6a7d3a300c..0000000000 --- a/tests/headers/bindgen-union-inside-namespace.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --enable-cxx-namespaces - -namespace foo { - union Bar { - int foo; - int bar; - }; -} diff --git a/tests/headers/bitfield-enum-repr-c.hpp b/tests/headers/bitfield-enum-repr-c.hpp deleted file mode 100644 index 20a3f9dbbe..0000000000 --- a/tests/headers/bitfield-enum-repr-c.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --bitfield-enum "Foo" --rust-target 1.27 -- -std=c++11 - -enum Foo { - Bar = 1 << 1, - Baz = 1 << 2, - Duplicated = 1 << 2, - Negative = -3, -}; diff --git a/tests/headers/bitfield-enum-repr-transparent.hpp b/tests/headers/bitfield-enum-repr-transparent.hpp deleted file mode 100644 index e53bb0753c..0000000000 --- a/tests/headers/bitfield-enum-repr-transparent.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --bitfield-enum "Foo" --rust-target 1.28 -- -std=c++11 - -enum Foo { - Bar = 1 << 1, - Baz = 1 << 2, - Duplicated = 1 << 2, - Negative = -3, -}; diff --git a/tests/headers/bitfield-linux-32.hpp b/tests/headers/bitfield-linux-32.hpp deleted file mode 100644 index b9a480df15..0000000000 --- a/tests/headers/bitfield-linux-32.hpp +++ /dev/null @@ -1,9 +0,0 @@ -// bindgen-flags: -- --target=i586-unknown-linux - -typedef unsigned long long uint64_t; - -struct Test { - uint64_t foo; - uint64_t x : 56; - uint64_t y : 8; -}; diff --git a/tests/headers/bitfield_align_2.h b/tests/headers/bitfield_align_2.h deleted file mode 100644 index b6a6cd284c..0000000000 --- a/tests/headers/bitfield_align_2.h +++ /dev/null @@ -1,12 +0,0 @@ -// bindgen-flags: --rustified-enum ".*" -enum MyEnum { - ONE, - TWO, - THREE, - FOUR -}; - -struct TaggedPtr { - enum MyEnum tag : 2; - long ptr : 62; -}; diff --git a/tests/headers/bitfield_pragma_packed.h b/tests/headers/bitfield_pragma_packed.h deleted file mode 100644 index b4011ca844..0000000000 --- a/tests/headers/bitfield_pragma_packed.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma pack(push, 1) -struct Struct { - unsigned char a : 1; - unsigned char b : 1; - unsigned char c : 6; - unsigned short int d : 16; - unsigned char e : 8; -}; -#pragma pack(pop) diff --git a/tests/headers/class_1_0.hpp b/tests/headers/class_1_0.hpp deleted file mode 100644 index e3735eb68d..0000000000 --- a/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/tests/headers/class_with_inner_struct_1_0.hpp b/tests/headers/class_with_inner_struct_1_0.hpp deleted file mode 100644 index 34ed96e722..0000000000 --- a/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/tests/headers/derive-clone.h b/tests/headers/derive-clone.h deleted file mode 100644 index aacbcaf885..0000000000 --- a/tests/headers/derive-clone.h +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.40 -// - -/// This struct should derive `Clone`. -struct ShouldDeriveClone { - int large[33]; -}; diff --git a/tests/headers/derive-clone_1_0.h b/tests/headers/derive-clone_1_0.h deleted file mode 100644 index 34ef40ae97..0000000000 --- a/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/tests/headers/derive-debug-bitfield.hpp b/tests/headers/derive-debug-bitfield.hpp deleted file mode 100644 index b68919054a..0000000000 --- a/tests/headers/derive-debug-bitfield.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 - -class C { - bool a: 1; - bool b: 7; - int large_array[50]; -}; diff --git a/tests/headers/derive-debug-function-pointer.hpp b/tests/headers/derive-debug-function-pointer.hpp deleted file mode 100644 index 147097fbd8..0000000000 --- a/tests/headers/derive-debug-function-pointer.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 - -class Nice { - typedef void (*Function) (int data); - Function pointer; - int large_array[34]; -}; diff --git a/tests/headers/derive-debug-generic.hpp b/tests/headers/derive-debug-generic.hpp deleted file mode 100644 index 50122fafa5..0000000000 --- a/tests/headers/derive-debug-generic.hpp +++ /dev/null @@ -1,6 +0,0 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 - -template -class Generic { - T t[40]; -}; diff --git a/tests/headers/derive-debug-opaque.hpp b/tests/headers/derive-debug-opaque.hpp deleted file mode 100644 index 715d3c89f1..0000000000 --- a/tests/headers/derive-debug-opaque.hpp +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --opaque-type "Opaque" --impl-debug --rust-target 1.40 - -class Opaque { - int i; - int not_debug[40]; -}; - -class OpaqueUser { - Opaque opaque; -}; diff --git a/tests/headers/derive-partialeq-base.hpp b/tests/headers/derive-partialeq-base.hpp deleted file mode 100644 index 2a57dca47d..0000000000 --- a/tests/headers/derive-partialeq-base.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --rust-target 1.40 - -class Base { - int large[33]; -}; - -class ShouldDerivePartialEq: Base { -}; diff --git a/tests/headers/derive-partialeq-bitfield.hpp b/tests/headers/derive-partialeq-bitfield.hpp deleted file mode 100644 index f6dd82e572..0000000000 --- a/tests/headers/derive-partialeq-bitfield.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --rust-target 1.40 - -class C { - bool a: 1; - bool b: 7; - int large_array[50]; -}; diff --git a/tests/headers/derive-partialeq-core.h b/tests/headers/derive-partialeq-core.h deleted file mode 100644 index 18eed8b324..0000000000 --- a/tests/headers/derive-partialeq-core.h +++ /dev/null @@ -1,5 +0,0 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --use-core --raw-line "extern crate core;" --rust-target 1.40 - -struct C { - int large_array[420]; -}; diff --git a/tests/headers/derive-partialeq-union_1_0.hpp b/tests/headers/derive-partialeq-union_1_0.hpp deleted file mode 100644 index d546d77b10..0000000000 --- a/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/tests/headers/empty-union.hpp b/tests/headers/empty-union.hpp deleted file mode 100644 index 3b067e39da..0000000000 --- a/tests/headers/empty-union.hpp +++ /dev/null @@ -1,5 +0,0 @@ -// bindgen-flags: --opaque-type "*" - -template class a { - union {}; -}; diff --git a/tests/headers/enum-doc.h b/tests/headers/enum-doc.h deleted file mode 100644 index 58e2c69e13..0000000000 --- a/tests/headers/enum-doc.h +++ /dev/null @@ -1,18 +0,0 @@ -/** Document enum */ -enum B { - /// Document field with three slashes - VAR_A = 0, - /** Document field with preceeding star */ - VAR_B = 1, - /*! Document field with preceeding exclamation */ - VAR_C = 2, - VAR_D = 3, /**< Document field with following star */ - VAR_E = 4, /*!< Document field with following exclamation */ - /** - * Document field with preceeding star, with a loong long multiline - * comment. - * - * Very interesting documentation, definitely. - */ - VAR_F, -}; diff --git a/tests/headers/enum_explicit_type_constants.hpp b/tests/headers/enum_explicit_type_constants.hpp deleted file mode 100644 index 7deab3699a..0000000000 --- a/tests/headers/enum_explicit_type_constants.hpp +++ /dev/null @@ -1,5 +0,0 @@ -// bindgen-flags: -- -std=c++11 -// -// This test is much like enum_explicit_type, but without --rustified-enum. - -#include "enum_explicit_type.hpp" diff --git a/tests/headers/extern-const-struct.h b/tests/headers/extern-const-struct.h deleted file mode 100644 index 1027127428..0000000000 --- a/tests/headers/extern-const-struct.h +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.40 - -struct nsFoo { - float details[400]; -}; - -extern const struct nsFoo gDetails; diff --git a/tests/headers/forward_declared_complex_types_1_0.hpp b/tests/headers/forward_declared_complex_types_1_0.hpp deleted file mode 100644 index ff6076fc43..0000000000 --- a/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/tests/headers/forward_declared_opaque.h b/tests/headers/forward_declared_opaque.h deleted file mode 100644 index 1b58edb9a8..0000000000 --- a/tests/headers/forward_declared_opaque.h +++ /dev/null @@ -1,4 +0,0 @@ -// bindgen-flags: --opaque-type "*" - -union a; -struct b; \ No newline at end of file diff --git a/tests/headers/i128.h b/tests/headers/i128.h deleted file mode 100644 index 6ec399c726..0000000000 --- a/tests/headers/i128.h +++ /dev/null @@ -1,6 +0,0 @@ -// bindgen-flags: --rust-target 1.26 - -struct foo { - __int128 my_signed; - unsigned __int128 my_unsigned; -}; diff --git a/tests/headers/infinite-macro.h b/tests/headers/infinite-macro.h deleted file mode 100644 index ab352c5785..0000000000 --- a/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/tests/headers/issue-372.hpp b/tests/headers/issue-372.hpp deleted file mode 100644 index a2a5d45122..0000000000 --- a/tests/headers/issue-372.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// bindgen-flags: --enable-cxx-namespaces --rustified-enum ".*" --rust-target 1.40 -template class c { a e[b]; }; -class d; -template class C { c h; }; -class i { - i *j; - i *k; - bool l; -}; -class d { - i m; -}; -enum n { o, p, q, r, s, t, b, ae, e, ag, ah, ai }; -class F { - C w; -}; diff --git a/tests/headers/issue-493_1_0.hpp b/tests/headers/issue-493_1_0.hpp deleted file mode 100644 index af6fd47c41..0000000000 --- a/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/tests/headers/issue-537-repr-packed-n.h b/tests/headers/issue-537-repr-packed-n.h deleted file mode 100644 index f4c0070a4a..0000000000 --- a/tests/headers/issue-537-repr-packed-n.h +++ /dev/null @@ -1,34 +0,0 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.33 - -/// This should not be opaque; we can see the attributes and can pack the -/// struct. -struct AlignedToOne { - int i; -} __attribute__ ((packed,aligned(1))); - -/// This should be be packed because Rust 1.33 has `#[repr(packed(N))]`. -struct AlignedToTwo { - int i; -} __attribute__ ((packed,aligned(2))); - -#pragma pack(1) - -/// 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. -struct PackedToOne { - int x; - int y; -}; - -#pragma pack() - -#pragma pack(2) - -/// This should be be packed because Rust 1.33 has `#[repr(packed(N))]`. -struct PackedToTwo { - int x; - int y; -}; - -#pragma pack() diff --git a/tests/headers/issue-544-stylo-creduce-2.hpp b/tests/headers/issue-544-stylo-creduce-2.hpp deleted file mode 100644 index f3467f4528..0000000000 --- a/tests/headers/issue-544-stylo-creduce-2.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: -- -std=c++14 - -template -struct Foo { - template using FirstAlias = typename T::Associated; - template using SecondAlias = Foo>; - SecondAlias member; -}; diff --git a/tests/headers/jsval_layout_opaque_1_0.hpp b/tests/headers/jsval_layout_opaque_1_0.hpp deleted file mode 100644 index c8e665516b..0000000000 --- a/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/tests/headers/layout_eth_conf_1_0.h b/tests/headers/layout_eth_conf_1_0.h deleted file mode 100644 index 48ba39ff87..0000000000 --- a/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/tests/headers/layout_mbuf_1_0.h b/tests/headers/layout_mbuf_1_0.h deleted file mode 100644 index 2854de5038..0000000000 --- a/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/tests/headers/long_double.h b/tests/headers/long_double.h deleted file mode 100644 index 91c4ed6ce9..0000000000 --- a/tests/headers/long_double.h +++ /dev/null @@ -1,5 +0,0 @@ -// bindgen-flags: --rust-target 1.26 - -struct foo { - long double bar; -}; diff --git a/tests/headers/macro_const_1_0.h b/tests/headers/macro_const_1_0.h deleted file mode 100644 index 3be86b4fd2..0000000000 --- a/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/tests/headers/newtype-enum.hpp b/tests/headers/newtype-enum.hpp deleted file mode 100644 index 890683ae85..0000000000 --- a/tests/headers/newtype-enum.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --newtype-enum "Foo" --rust-target 1.28 -- -std=c++11 - -enum Foo { - Bar = 1 << 1, - Baz = 1 << 2, - Duplicated = 1 << 2, - Negative = -3, -}; diff --git a/tests/headers/no_debug_bypass_impl_debug.hpp b/tests/headers/no_debug_bypass_impl_debug.hpp deleted file mode 100644 index d934d2c7cb..0000000000 --- a/tests/headers/no_debug_bypass_impl_debug.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --no-debug "NoDebug" --impl-debug --rust-target 1.40 - -template -class Generic { - T t[40]; -}; - -template -class NoDebug { - T t[40]; -}; diff --git a/tests/headers/no_default_bypass_derive_default.hpp b/tests/headers/no_default_bypass_derive_default.hpp deleted file mode 100644 index ab0fdfae9f..0000000000 --- a/tests/headers/no_default_bypass_derive_default.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --no-default "NoDefault" --rust-target 1.40 - -template -class Generic { - T t[40]; -}; - -template -class NoDefault { - T t[40]; -}; diff --git a/tests/headers/objc_category.h b/tests/headers/objc_category.h deleted file mode 100644 index c464b72eb2..0000000000 --- a/tests/headers/objc_category.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo --(void)method; -@end - -@interface Foo (BarCategory) --(void)categoryMethod; -@end diff --git a/tests/headers/objc_class.h b/tests/headers/objc_class.h deleted file mode 100644 index cea72e78aa..0000000000 --- a/tests/headers/objc_class.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@class Foo; - -Foo* fooVar; - -@interface Foo --(void)method; -@end diff --git a/tests/headers/objc_inheritance.h b/tests/headers/objc_inheritance.h deleted file mode 100644 index 8f96e45ba8..0000000000 --- a/tests/headers/objc_inheritance.h +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo -@end - -@interface Bar: Foo -@end - -@interface Baz: Bar -@end diff --git a/tests/headers/objc_interface.h b/tests/headers/objc_interface.h deleted file mode 100644 index af84bf925a..0000000000 --- a/tests/headers/objc_interface.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo -@end - -@protocol bar -@end diff --git a/tests/headers/objc_interface_type.h b/tests/headers/objc_interface_type.h deleted file mode 100644 index 31d33664c1..0000000000 --- a/tests/headers/objc_interface_type.h +++ /dev/null @@ -1,13 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo -@end - -struct FooStruct { - Foo *foo; -}; - -void fooFunc(Foo *foo); - -static const Foo *kFoo; diff --git a/tests/headers/objc_method_clash.h b/tests/headers/objc_method_clash.h deleted file mode 100644 index a56e39dba8..0000000000 --- a/tests/headers/objc_method_clash.h +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo -+ (void)foo; -- (void)foo; -@end diff --git a/tests/headers/objc_pointer_return_types.h b/tests/headers/objc_pointer_return_types.h deleted file mode 100644 index e289a8a53d..0000000000 --- a/tests/headers/objc_pointer_return_types.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Bar -@end - -@interface Foo -+ (Bar*)methodReturningBar; -- (void)methodUsingBar:(Bar *)my_bar; -@end diff --git a/tests/headers/objc_property_fnptr.h b/tests/headers/objc_property_fnptr.h deleted file mode 100644 index bac0c779a9..0000000000 --- a/tests/headers/objc_property_fnptr.h +++ /dev/null @@ -1,6 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@interface Foo -@property int (*func)(char, short, float); -@end diff --git a/tests/headers/objc_protocol.h b/tests/headers/objc_protocol.h deleted file mode 100644 index 0c760fa51f..0000000000 --- a/tests/headers/objc_protocol.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@protocol Foo -@end - -@interface Foo -@end diff --git a/tests/headers/objc_protocol_inheritance.h b/tests/headers/objc_protocol_inheritance.h deleted file mode 100644 index d5f3a490e5..0000000000 --- a/tests/headers/objc_protocol_inheritance.h +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -@protocol Foo -@end - -@interface Foo -@end - -@interface Bar : Foo -@end diff --git a/tests/headers/objc_sel_and_id.h b/tests/headers/objc_sel_and_id.h deleted file mode 100644 index 3c8c656166..0000000000 --- a/tests/headers/objc_sel_and_id.h +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --objc-extern-crate -- -x objective-c -// bindgen-osx-only - -id object; -SEL selector; - -void f(id object, SEL selector); diff --git a/tests/headers/ord-enum.h b/tests/headers/ord-enum.h deleted file mode 100644 index 364f711efa..0000000000 --- a/tests/headers/ord-enum.h +++ /dev/null @@ -1,15 +0,0 @@ -// bindgen-flags: --rustified-enum * --with-derive-ord - -enum A { - A0 = 0, - A1 = 1, - A2 = 2, - A3 = A0 - 1, -}; - -enum B { - B0 = 1, - B1 = B0 + 3, - B2 = B0 + 2, - B3 = B0 - 2, -}; \ No newline at end of file diff --git a/tests/headers/packed-vtable.h b/tests/headers/packed-vtable.h deleted file mode 100644 index d2413d4571..0000000000 --- a/tests/headers/packed-vtable.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.33 -- -x c++ -std=c++11 - -#pragma pack(1) - -// This should be packed. -struct PackedVtable { - virtual ~PackedVtable(); -}; - -#pragma pack() diff --git a/tests/headers/private_fields.hpp b/tests/headers/private_fields.hpp deleted file mode 100644 index 9d55ebcac8..0000000000 --- a/tests/headers/private_fields.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// bindgen-flags: --respect-cxx-access-specs -class PubPriv { - public: - int x; - private: - int y; -}; - -class PrivateBitFields { - unsigned int a : 4; - unsigned int b : 4; -}; -class PublicBitFields { - public: - unsigned int a : 4; - unsigned int b : 4; -}; -class MixedBitFields { - unsigned int a : 4; - public: - unsigned int d : 4; -}; - -class Base { - public: - int member; -}; - -class InheritsPrivately : Base {}; -class InheritsPublically : public Base {}; - -class WithAnonStruct { - struct { - int a; - }; - public: - struct { - int b; - }; -}; - -class WithAnonUnion { - union {}; -}; \ No newline at end of file diff --git a/tests/headers/public-dtor.hpp b/tests/headers/public-dtor.hpp deleted file mode 100644 index 5d4fb592a1..0000000000 --- a/tests/headers/public-dtor.hpp +++ /dev/null @@ -1,15 +0,0 @@ - - -namespace cv { -class String { -public: - ~String(); -}; - - -inline -String::~String() -{ -} - -} diff --git a/tests/headers/repr-align.hpp b/tests/headers/repr-align.hpp deleted file mode 100644 index 3347594b5c..0000000000 --- a/tests/headers/repr-align.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.25 -- -std=c++11 - -struct alignas(8) a { - int b; - int c; -}; - -struct alignas(double) b { - int b; - int c; -}; diff --git a/tests/headers/size_t_is_usize.h b/tests/headers/size_t_is_usize.h deleted file mode 100644 index 564b486784..0000000000 --- a/tests/headers/size_t_is_usize.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --size_t-is-usize - -typedef unsigned long size_t; -typedef long ssize_t; - -struct A { - size_t len; - ssize_t offset; - struct A* next; -}; diff --git a/tests/headers/struct_with_anon_union_1_0.h b/tests/headers/struct_with_anon_union_1_0.h deleted file mode 100644 index 847c354b59..0000000000 --- a/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/tests/headers/struct_with_anon_unnamed_union_1_0.h b/tests/headers/struct_with_anon_unnamed_union_1_0.h deleted file mode 100644 index 791a1593af..0000000000 --- a/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/tests/headers/struct_with_nesting_1_0.h b/tests/headers/struct_with_nesting_1_0.h deleted file mode 100644 index a24ae1db58..0000000000 --- a/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/tests/headers/typeref_1_0.hpp b/tests/headers/typeref_1_0.hpp deleted file mode 100644 index 70dfc11fb1..0000000000 --- a/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/tests/headers/union-align.h b/tests/headers/union-align.h deleted file mode 100644 index 9557b2798a..0000000000 --- a/tests/headers/union-align.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --rust-target 1.26 - -union Bar { - unsigned char foo; -} __attribute__ ((__aligned__ (16))); - - -union Baz { - union Bar bar; -}; diff --git a/tests/headers/union-in-ns_1_0.hpp b/tests/headers/union-in-ns_1_0.hpp deleted file mode 100644 index f3ae221057..0000000000 --- a/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/tests/headers/union_bitfield.h b/tests/headers/union_bitfield.h deleted file mode 100644 index 990729574a..0000000000 --- a/tests/headers/union_bitfield.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --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; -}; diff --git a/tests/headers/union_bitfield_1_0.h b/tests/headers/union_bitfield_1_0.h deleted file mode 100644 index 06b61ad771..0000000000 --- a/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/tests/headers/union_dtor_1_0.hpp b/tests/headers/union_dtor_1_0.hpp deleted file mode 100644 index 01f7636671..0000000000 --- a/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/tests/headers/union_fields_1_0.hpp b/tests/headers/union_fields_1_0.hpp deleted file mode 100644 index bbb67fbc6e..0000000000 --- a/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/tests/headers/union_template_1_0.hpp b/tests/headers/union_template_1_0.hpp deleted file mode 100644 index 18e3d74a37..0000000000 --- a/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/tests/headers/union_with_anon_struct_1_0.h b/tests/headers/union_with_anon_struct_1_0.h deleted file mode 100644 index 9313299eb0..0000000000 --- a/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/tests/headers/union_with_anon_struct_bitfield_1_0.h b/tests/headers/union_with_anon_struct_bitfield_1_0.h deleted file mode 100644 index 0b0e3d7371..0000000000 --- a/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/tests/headers/union_with_anon_union_1_0.h b/tests/headers/union_with_anon_union_1_0.h deleted file mode 100644 index 28a7231dbf..0000000000 --- a/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/tests/headers/union_with_anon_unnamed_struct_1_0.h b/tests/headers/union_with_anon_unnamed_struct_1_0.h deleted file mode 100644 index 506a41f661..0000000000 --- a/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/tests/headers/union_with_anon_unnamed_union_1_0.h b/tests/headers/union_with_anon_unnamed_union_1_0.h deleted file mode 100644 index c556a61311..0000000000 --- a/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/tests/headers/union_with_big_member_1_0.h b/tests/headers/union_with_big_member_1_0.h deleted file mode 100644 index 0429435478..0000000000 --- a/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/tests/headers/union_with_nesting_1_0.h b/tests/headers/union_with_nesting_1_0.h deleted file mode 100644 index 3cdb7238bc..0000000000 --- a/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/tests/headers/use-core.h b/tests/headers/use-core.h deleted file mode 100644 index b4135b44a7..0000000000 --- a/tests/headers/use-core.h +++ /dev/null @@ -1,13 +0,0 @@ -// bindgen-flags: --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/tests/headers/use-core_1_0.h b/tests/headers/use-core_1_0.h deleted file mode 100644 index 40de9d158d..0000000000 --- a/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/tests/headers/virtual_inheritance.hpp b/tests/headers/virtual_inheritance.hpp deleted file mode 100644 index 5198c51e27..0000000000 --- a/tests/headers/virtual_inheritance.hpp +++ /dev/null @@ -1,16 +0,0 @@ - -class A { - int foo; -}; - -class B: public virtual A { - int bar; -}; - -class C: public virtual A { - int baz; -}; - -class D: public C, public B { - int bazz; -}; diff --git a/tests/headers/win32-thiscall_1_0.hpp b/tests/headers/win32-thiscall_1_0.hpp deleted file mode 100644 index 5907c76eaf..0000000000 --- a/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/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs deleted file mode 100644 index b94b54de0b..0000000000 --- a/tests/parse_callbacks/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -use bindgen::callbacks::*; - -#[derive(Debug)] -struct EnumVariantRename; - -impl ParseCallbacks for EnumVariantRename { - fn enum_variant_name( - &self, - _enum_name: Option<&str>, - original_variant_name: &str, - _variant_value: EnumVariantValue, - ) -> Option { - Some(format!("RENAMED_{}", original_variant_name)) - } -} - -#[derive(Debug)] -struct BlocklistedTypeImplementsTrait; - -impl ParseCallbacks for BlocklistedTypeImplementsTrait { - fn blocklisted_type_implements_trait( - &self, - _name: &str, - derive_trait: DeriveTrait, - ) -> Option { - if derive_trait == DeriveTrait::Hash { - Some(ImplementsTrait::No) - } else { - Some(ImplementsTrait::Yes) - } - } -} - -pub fn lookup(cb: &str) -> Box { - match cb { - "enum-variant-rename" => Box::new(EnumVariantRename), - "blocklisted-type-implements-trait" => { - Box::new(BlocklistedTypeImplementsTrait) - } - _ => panic!("Couldn't find name ParseCallbacks: {}", cb), - } -} diff --git a/tests/quickchecking/Cargo.toml b/tests/quickchecking/Cargo.toml deleted file mode 100644 index ddefb33d69..0000000000 --- a/tests/quickchecking/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[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.1.0" -authors = ["Shea Newton "] - -[lib] -name = "quickchecking" -path = "src/lib.rs" - -[[bin]] -name = "quickchecking" -path = "src/bin.rs" - -[dependencies] -clap = "2.28" -lazy_static = "1.0" -quickcheck = "0.4" -rand = "0.3" -tempdir = "0.3" - -[features] -# No features by default. -default = [] - -# Enable the generation of code that allows for zero sized arrays as struct -# fields. Until issues #684 and #1153 are resolved this can result in failing tests. -zero-sized-arrays = [] - -# Enable the generation of code that allows for long double types as struct -# fields. Until issue #550 is resolved this can result in failing tests. -long-doubles = [] diff --git a/tests/quickchecking/README.md b/tests/quickchecking/README.md deleted file mode 100644 index d3cfe17071..0000000000 --- a/tests/quickchecking/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Property tests for `bindgen` with `quickchecking` - -`quickchecking` generates random C headers to test `bindgen` -using the [`quickcheck`][quickcheck] property testing crate. When testing -`bindgen` with `quickchecking`, the generated header files are passed to -`bindgen`'s `csmith-fuzzing/predicate.py` script. If that script fails, -`quickchecking` panics, and you can report an issue containing the test case! - - - - - -- [Prerequisites](#prerequisites) -- [Running](#running) - - - -## Prerequisites - -Requires `python3` to be in `$PATH`. - -Many systems have `python3` by default but if your OS doesn't, its package -manager may make it available: - -``` -$ sudo apt install python3 -$ brew install python3 -$ # Etc... -``` - -## Running - -Run `quickchecking` binary to generate and test fuzzed C headers with -`cargo run`. Additional configuration is exposed through the binary's CLI. - -``` -$ cargo run --bin=quickchecking -- -h -``` -[quickcheck]: https://github.com/BurntSushi/quickcheck diff --git a/tests/quickchecking/src/bin.rs b/tests/quickchecking/src/bin.rs deleted file mode 100644 index d2774eb0d9..0000000000 --- a/tests/quickchecking/src/bin.rs +++ /dev/null @@ -1,110 +0,0 @@ -//! An application to run property tests for `bindgen` with _fuzzed_ C headers -//! using `quickcheck` -//! -//! ## Usage -//! -//! Print help -//! ```bash -//! $ cargo run --bin=quickchecking -- -h -//! ``` -//! -//! Run with default values -//! ```bash -//! $ cargo run --bin=quickchecking -//! ``` -//! -#![deny(missing_docs)] -extern crate clap; -extern crate quickchecking; - -use clap::{App, Arg}; -use std::path::Path; - -// Validate CLI argument input for generation range. -fn validate_generate_range(v: String) -> Result<(), String> { - match v.parse::() { - Ok(_) => Ok(()), - Err(_) => Err(String::from( - "Generate range could not be converted to a usize.", - )), - } -} - -// Validate CLI argument input for tests count. -fn validate_tests_count(v: String) -> Result<(), String> { - match v.parse::() { - Ok(_) => Ok(()), - Err(_) => Err(String::from( - "Tests count could not be converted to a usize.", - )), - } -} - -// Validate CLI argument input for fuzzed headers output path. -fn validate_path(v: String) -> Result<(), String> { - match Path::new(&v).is_dir() { - true => Ok(()), - false => Err(String::from("Provided directory path does not exist.")), - } -} - -fn main() { - let matches = App::new("quickchecking") - .version("0.2.0") - .about( - "Bindgen property tests with quickcheck. \ - Generate random valid C code and pass it to the \ - csmith/predicate.py script", - ) - .arg( - Arg::with_name("path") - .short("p") - .long("path") - .value_name("PATH") - .help( - "Optional. Preserve generated headers for inspection, \ - provide directory path for header output. [default: None] ", - ) - .takes_value(true) - .validator(validate_path), - ) - .arg( - Arg::with_name("range") - .short("r") - .long("range") - .value_name("RANGE") - .help( - "Sets the range quickcheck uses during generation. \ - Corresponds to things like arbitrary usize and \ - arbitrary vector length. This number doesn't have \ - to grow much for execution time to increase \ - significantly.", - ) - .takes_value(true) - .default_value("32") - .validator(validate_generate_range), - ) - .arg( - Arg::with_name("count") - .short("c") - .long("count") - .value_name("COUNT") - .help( - "Count / number of tests to run. Running a fuzzed \ - header through the predicate.py script can take a \ - long time, especially if the generation range is \ - large. Increase this number if you're willing to \ - wait a while.", - ) - .takes_value(true) - .default_value("2") - .validator(validate_tests_count), - ) - .get_matches(); - - let output_path: Option<&str> = matches.value_of("path"); - let generate_range: usize = matches.value_of("range").unwrap().parse::().unwrap(); - let tests: usize = matches.value_of("count").unwrap().parse::().unwrap(); - - quickchecking::test_bindgen(generate_range, tests, output_path) -} diff --git a/tests/quickchecking/src/fuzzers.rs b/tests/quickchecking/src/fuzzers.rs deleted file mode 100644 index 7c76442515..0000000000 --- a/tests/quickchecking/src/fuzzers.rs +++ /dev/null @@ -1,637 +0,0 @@ -use quickcheck::{Arbitrary, Gen, StdGen}; -use std::fmt; -use rand::thread_rng; - -/// 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 { - /// String representation of C type. - pub def: String, -} - -/// TypeQualifierC is used in generation of C headers to represent qualifiers -/// such as `const`. -#[derive(Debug, Clone)] -pub struct TypeQualifierC { - /// String representation of C type qualifier. - pub def: String, -} - -/// PointerLevelC is used in generation of C headers to represent number of -/// `*` for pointer types. -#[derive(Debug, Clone)] -pub struct PointerLevelC { - /// String representation of C declaration's pointer level. - pub def: String, -} - -/// ArrayDimensionC is used in generation of C headers to represent number of -/// `[]` used to define array types. -#[derive(Debug, Clone)] -pub struct ArrayDimensionC { - /// String representation of C declaration's array dimension. - pub def: String, -} - -/// 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)] -pub struct BasicTypeDeclarationC { - /// The declaration's base type, i.e. `int`. - pub type_name: BaseTypeC, - /// The declaration's type qualifier, i.e. `const`. - pub type_qualifier: TypeQualifierC, - /// The declaration's pointer level, i.e. `***`. - pub pointer_level: PointerLevelC, - /// The declaration's array dimension, i.e. [][][]. - pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. ident_N. - pub ident_id: String, -} - -/// StructDeclarationC is used in generation of C headers to represent the -/// definition of a struct type. -#[derive(Debug, Clone)] -pub struct StructDeclarationC { - /// The declaration's fields. - pub fields: DeclarationListC, - /// The declaration's array dimension, i.e. [][][]. - pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. struct_N. - pub ident_id: String, -} - -/// UnionDeclarationC is used in generation of C headers to represent the -/// definition of a union type. -#[derive(Debug, Clone)] -pub struct UnionDeclarationC { - /// The declaration's fields. - pub fields: DeclarationListC, - /// The declaration's array dimension, i.e. [][][]. - pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. union_N. - pub ident_id: String, -} - -/// FunctionPointerDeclarationC is used in generation of C headers to represent -/// the definition of a function pointer type. -#[derive(Debug, Clone)] -pub struct FunctionPointerDeclarationC { - /// The function's type qualifier, i.e. `const`. - pub type_qualifier: TypeQualifierC, - /// The function's return type, i.e. `int`. - pub type_name: BaseTypeC, - /// The function's pointer level, i.e. `***`. - pub pointer_level: PointerLevelC, - /// The function's parameters. - pub params: ParameterListC, - /// The declaration's identifier, i.e. func_ptr_N. - pub ident_id: String, -} - -/// FunctionPrototypeC is used in generation of C headers to represent the -/// definition of a function prototype. -#[derive(Debug, Clone)] -pub struct FunctionPrototypeC { - /// The function's type qualifier, i.e. `const`. - pub type_qualifier: TypeQualifierC, - /// The function's return type, i.e. `int`. - pub type_name: BaseTypeC, - /// The function's pointer level, i.e. `***`. - pub pointer_level: PointerLevelC, - /// The function's parameters. - pub params: ParameterListC, - /// The prototype's identifier, i.e. `func_N`. - pub ident_id: String, -} - -/// ParameterC is used in generation of C headers to represent the -/// definition function parameters. -#[derive(Debug, Clone)] -pub struct ParameterC { - /// The parameter's type qualifier, i.e. `const`. - pub type_qualifier: TypeQualifierC, - /// The parameter's base type, i.e. `int`. - pub type_name: BaseTypeC, - /// The parameter's pointer level, i.e. `***`. - pub pointer_level: PointerLevelC, -} - -/// ParameterListC is used in generation of C headers to represent a list of -/// definitions of function parameters. -#[derive(Debug, Clone)] -pub struct ParameterListC { - /// Parameters that define a C function signature. - pub params: Vec, -} - -/// 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 { - /// Function prototype declaration kind. - FunctionDecl(FunctionPrototypeC), - /// Function pointer declaration kind. - FunctionPtrDecl(FunctionPointerDeclarationC), - /// Struct declaration kind. - StructDecl(StructDeclarationC), - /// Union declaration kind. - UnionDecl(UnionDeclarationC), - /// Basic type declaration kind. - VariableDecl(BasicTypeDeclarationC), -} - -/// DeclarationListC is used in generation of C headers to represent a list of -/// declarations. -#[derive(Debug, Clone)] -pub struct DeclarationListC { - /// Grouping of C declarations. - pub decls: Vec, -} - -/// HeaderC is used in generation of C headers to represent a collection of -/// declarations. -#[derive(Clone)] -pub struct HeaderC { - /// The header's declarations. - pub def: DeclarationListC, -} - -/// 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 -/// identifiers unique. -impl MakeUnique for DeclarationC { - fn make_unique(&mut self, stamp: usize) { - match *self { - DeclarationC::FunctionDecl(ref mut d) => d.make_unique(stamp), - DeclarationC::FunctionPtrDecl(ref mut d) => d.make_unique(stamp), - DeclarationC::StructDecl(ref mut d) => d.make_unique(stamp), - DeclarationC::UnionDecl(ref mut d) => d.make_unique(stamp), - DeclarationC::VariableDecl(ref mut d) => d.make_unique(stamp), - } - } -} - -/// A qucickcheck trait for describing how DeclarationC types can be -/// randomly generated and shrunk. -impl Arbitrary for DeclarationC { - fn arbitrary(g: &mut G) -> DeclarationC { - match g.gen_range(0, 5) { - 0 => DeclarationC::FunctionDecl(FunctionPrototypeC::arbitrary(g)), - 1 => DeclarationC::FunctionPtrDecl(FunctionPointerDeclarationC::arbitrary(g)), - 2 => DeclarationC::StructDecl(StructDeclarationC::arbitrary(g)), - 3 => DeclarationC::UnionDecl(UnionDeclarationC::arbitrary(g)), - 4 => DeclarationC::VariableDecl(BasicTypeDeclarationC::arbitrary(g)), - _ => unreachable!(), - } - } -} - -/// 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), - } - } -} - -/// A qucickcheck trait for describing how DeclarationListC types can be -/// randomly generated and shrunk. -impl Arbitrary for DeclarationListC { - fn arbitrary(g: &mut G) -> DeclarationListC { - DeclarationListC { - decls: Arbitrary::arbitrary(g), - } - } -} - -/// 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, "{}", display) - } -} - -/// A qucickcheck trait for describing how BaseTypeC types can be -/// randomly generated and shrunk. -impl Arbitrary for BaseTypeC { - fn arbitrary(g: &mut G) -> BaseTypeC { - // Special case `long double` until issue #550 is resolved. - let base_type = vec![ - "char", - "signed char", - "unsigned char", - "short", - "short int", - "signed short", - "signed short int", - "unsigned short", - "unsigned short int", - "int", - "signed", - "signed int", - "unsigned", - "unsigned int", - "long", - "long int", - "signed long", - "signed long int", - "unsigned long", - "unsigned long int", - "long long", - "long long int", - "signed long long", - "signed long long int", - "unsigned long long", - "unsigned long long int", - "float", - "double", - #[cfg(feature = "long-doubles")] - "long double", - "void*", - ]; - BaseTypeC { - def: String::from(*g.choose(&base_type).unwrap()), - } - } -} - -/// 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 -/// randomly generated and shrunk. -impl Arbitrary for TypeQualifierC { - fn arbitrary(g: &mut G) -> TypeQualifierC { - let qualifier = vec!["const", ""]; - TypeQualifierC { - def: String::from(*g.choose(&qualifier).unwrap()), - } - } -} - -/// 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 -/// randomly generated and shrunk. -impl Arbitrary for PointerLevelC { - fn arbitrary(g: &mut G) -> PointerLevelC { - PointerLevelC { - // 16 is an arbitrary "not too big" number for capping pointer level. - def: (0..g.gen_range(0, 16)).map(|_| "*").collect::(), - } - } -} - -/// 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 -/// randomly generated and shrunk. -impl Arbitrary for ArrayDimensionC { - fn arbitrary(g: &mut G) -> ArrayDimensionC { - // Keep these small, clang complains when they get too big. - let dimensions = g.gen_range(0, 5); - let mut def = String::new(); - - let lower_bound; - if cfg!(feature = "zero-sized-arrays") { - lower_bound = 0; - } else { - lower_bound = 1; - } - - for _ in 1..dimensions { - // 16 is an arbitrary "not too big" number for capping array size. - def += &format!("[{}]", g.gen_range(lower_bound, 16)); - } - ArrayDimensionC { def } - } -} - -/// 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 -/// identifiers unique. -impl MakeUnique for BasicTypeDeclarationC { - fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); - } -} - -/// A qucickcheck trait for describing how BasicTypeDeclarationC types can be -/// randomly generated and shrunk. -impl Arbitrary for BasicTypeDeclarationC { - fn arbitrary(g: &mut G) -> BasicTypeDeclarationC { - BasicTypeDeclarationC { - type_qualifier: Arbitrary::arbitrary(g), - type_name: Arbitrary::arbitrary(g), - pointer_level: Arbitrary::arbitrary(g), - array_dimension: Arbitrary::arbitrary(g), - ident_id: format!("{}", usize::arbitrary(g)), - } - } -} - -/// Enables to string and format for BasicTypeDeclarationC types. -impl fmt::Display for BasicTypeDeclarationC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} {} {} ident_{}{};", - self.type_qualifier, - self.type_name, - self.pointer_level, - self.ident_id, - self.array_dimension - ) - } -} - -/// 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); - } -} - -/// A qucickcheck trait for describing how StructDeclarationC types can be -/// randomly generated and shrunk. -impl Arbitrary for StructDeclarationC { - fn arbitrary(g: &mut G) -> StructDeclarationC { - // Reduce generator size as a method of putting a bound on recursion. - // When size < 1 the empty list is generated. - let reduced_size: usize = (g.size() / 2) as usize + 1; - let mut decl_list: DeclarationListC = - Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size)); - let mut fields: DeclarationListC = DeclarationListC { decls: vec![] }; - - for (i, decl) in decl_list.decls.iter_mut().enumerate() { - match *decl { - DeclarationC::FunctionDecl(_) => {} - ref mut decl => { - decl.make_unique(i); - fields.decls.push(decl.clone()); - } - } - } - - StructDeclarationC { - fields, - ident_id: format!("{}", usize::arbitrary(g)), - array_dimension: Arbitrary::arbitrary(g), - } - } -} - -/// Enables to string and format for StructDeclarationC types. -impl fmt::Display for StructDeclarationC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "struct {{ {} }} struct_{}{};", - self.fields, - self.ident_id, - self.array_dimension - ) - } -} - -/// 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); - } -} - -/// A qucickcheck trait for describing how UnionDeclarationC types can be -/// randomly generated and shrunk. -impl Arbitrary for UnionDeclarationC { - fn arbitrary(g: &mut G) -> UnionDeclarationC { - // Reduce generator size as a method of putting a bound on recursion. - // When size < 1 the empty list is generated. - let reduced_size: usize = (g.size() / 2) as usize + 1; - let mut decl_list: DeclarationListC = - Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size)); - let mut fields: DeclarationListC = DeclarationListC { decls: vec![] }; - - for (i, decl) in decl_list.decls.iter_mut().enumerate() { - match *decl { - DeclarationC::FunctionDecl(_) => {} - ref mut decl => { - decl.make_unique(i); - fields.decls.push(decl.clone()); - } - } - } - - UnionDeclarationC { - fields, - ident_id: format!("{}", usize::arbitrary(g)), - array_dimension: Arbitrary::arbitrary(g), - } - } -} - -/// Enables to string and format for UnionDeclarationC types. -impl fmt::Display for UnionDeclarationC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "union {{ {} }} union_{}{};", - self.fields, - self.ident_id, - self.array_dimension - ) - } -} - -/// 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); - } -} - -/// A qucickcheck trait for describing how FunctionPointerDeclarationC types can -/// be randomly generated and shrunk. -impl Arbitrary for FunctionPointerDeclarationC { - fn arbitrary(g: &mut G) -> FunctionPointerDeclarationC { - FunctionPointerDeclarationC { - type_qualifier: Arbitrary::arbitrary(g), - type_name: Arbitrary::arbitrary(g), - pointer_level: Arbitrary::arbitrary(g), - params: Arbitrary::arbitrary(g), - ident_id: format!("{}", usize::arbitrary(g)), - } - } -} - -/// Enables to string and format for FunctionPointerDeclarationC types. -impl fmt::Display for FunctionPointerDeclarationC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} {} {} (*func_ptr_{})({});", - self.type_qualifier, - self.type_name, - self.pointer_level, - self.ident_id, - self.params - ) - } -} - -/// 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); - } -} - -/// A qucickcheck trait for describing how FunctionPrototypeC types can be -/// randomly generated and shrunk. -impl Arbitrary for FunctionPrototypeC { - fn arbitrary(g: &mut G) -> FunctionPrototypeC { - FunctionPrototypeC { - type_qualifier: Arbitrary::arbitrary(g), - type_name: Arbitrary::arbitrary(g), - pointer_level: Arbitrary::arbitrary(g), - params: Arbitrary::arbitrary(g), - ident_id: format!("{}", usize::arbitrary(g)), - } - } -} - -/// Enables to string and format for FunctionPrototypeC types. -impl fmt::Display for FunctionPrototypeC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} {} {} func_{}({});", - self.type_qualifier, - self.type_name, - self.pointer_level, - self.ident_id, - self.params - ) - } -} - -/// A qucickcheck trait for describing how ParameterC types can be -/// randomly generated and shrunk. -impl Arbitrary for ParameterC { - fn arbitrary(g: &mut G) -> ParameterC { - ParameterC { - type_qualifier: Arbitrary::arbitrary(g), - type_name: Arbitrary::arbitrary(g), - pointer_level: Arbitrary::arbitrary(g), - } - } -} - -/// Enables to string and format for ParameterC types. -impl fmt::Display for ParameterC { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} {} {}", - self.type_qualifier, - self.type_name, - self.pointer_level - ) - } -} - -/// A qucickcheck trait for describing how ParameterListC types can be -/// randomly generated and shrunk. -impl Arbitrary for ParameterListC { - fn arbitrary(g: &mut G) -> ParameterListC { - ParameterListC { - params: Arbitrary::arbitrary(g), - } - } -} - -/// 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), - } - } - write!(f, "{}", display) - } -} - -/// A qucickcheck trait for describing how HeaderC types can be -/// randomly generated and shrunk. -impl Arbitrary for HeaderC { - fn arbitrary(g: &mut G) -> HeaderC { - let mut decl_list: DeclarationListC = Arbitrary::arbitrary(g); - for (i, decl) in decl_list.decls.iter_mut().enumerate() { - decl.make_unique(i); - } - HeaderC { def: decl_list } - } -} - -/// 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, "{}", display) - } -} - -/// Use Display trait for Debug so that any failing property tests report -/// 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) - } -} diff --git a/tests/quickchecking/src/lib.rs b/tests/quickchecking/src/lib.rs deleted file mode 100644 index d8633dfb92..0000000000 --- a/tests/quickchecking/src/lib.rs +++ /dev/null @@ -1,126 +0,0 @@ -//! A library to generate __fuzzed__ C headers for use with `quickcheck` -//! -//! ## Example -//! -//! ```rust -//! extern crate quickcheck; -//! extern crate quickchecking; -//! extern crate rand; -//! use quickcheck::{Arbitrary, Gen, StdGen}; -//! use quickchecking::fuzzers; -//! use rand::thread_rng; -//! -//! fn main() { -//! let generate_range: usize = 10; // Determines things like the length of -//! // arbitrary vectors generated. -//! let header = fuzzers::HeaderC::arbitrary( -//! &mut StdGen::new(thread_rng(), generate_range)); -//! println!("{}", header); -//! } -//! ``` -//! -#![deny(missing_docs)] -#[macro_use] -extern crate lazy_static; -extern crate quickcheck; -extern crate rand; -extern crate tempdir; - -use std::sync::Mutex; -use quickcheck::{QuickCheck, StdGen, TestResult}; -use std::fs::File; -use std::io::Write; -use tempdir::TempDir; -use std::process::{Command, Output}; -use std::path::PathBuf; -use std::error::Error; -use rand::thread_rng; - -/// Contains definitions of and impls for types used to fuzz C declarations. -pub mod fuzzers; - -// Global singleton, manages context across tests. For now that context is -// only the output_path for inspecting fuzzed headers (if specified). -struct Context { - output_path: Option, -} - -// Initialize global context. -lazy_static! { - static ref 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) -> Result> { - let dir = TempDir::new("bindgen_prop")?; - let header_path = dir.path().join("prop_test.h"); - - let mut header_file = File::create(&header_path)?; - header_file.write_all(header.to_string().as_bytes())?; - header_file.sync_all()?; - - let header_path_string; - match header_path.into_os_string().into_string() { - Ok(s) => header_path_string = s, - Err(_) => return Err(From::from("error converting path into String")), - } - - let mut predicate_script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - predicate_script_path.push("../../csmith-fuzzing/predicate.py"); - - let predicate_script_path_string; - match predicate_script_path.into_os_string().into_string() { - Ok(s) => predicate_script_path_string = s, - Err(_) => return Err(From::from("error converting path into String")), - } - - // Copy generated temp files to output_path directory for inspection. - // If `None`, output path not specified, don't copy. - match CONTEXT.lock().unwrap().output_path { - Some(ref path) => { - Command::new("cp") - .arg("-a") - .arg(&dir.path().to_str().unwrap()) - .arg(&path) - .output()?; - } - None => {} - } - - Ok(Command::new(&predicate_script_path_string) - .arg(&header_path_string) - .output()?) -} - -// 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. -fn bindgen_prop(header: fuzzers::HeaderC) -> TestResult { - match run_predicate_script(header) { - Ok(o) => return TestResult::from_bool(o.status.success()), - Err(e) => { - println!("{:?}", e); - return TestResult::from_bool(false); - } - } -} - -/// Instantiate a Quickcheck object and use it to run property tests using -/// fuzzed C headers generated with types defined in the `fuzzers` module. -/// Success/Failure is dictated by the result of passing the fuzzed headers -/// to the `csmith-fuzzing/predicate.py` script. -pub fn test_bindgen(generate_range: usize, tests: usize, output_path: Option<&str>) { - match output_path { - Some(path) => { - CONTEXT.lock().unwrap().output_path = - Some(String::from(PathBuf::from(path).to_str().unwrap())); - } - None => {} // Path not specified, don't provide output. - } - - QuickCheck::new() - .tests(tests) - .gen(StdGen::new(thread_rng(), generate_range)) - .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult) -} diff --git a/tests/quickchecking/tests/fuzzed-c-headers.rs b/tests/quickchecking/tests/fuzzed-c-headers.rs deleted file mode 100644 index 6b58d24b23..0000000000 --- a/tests/quickchecking/tests/fuzzed-c-headers.rs +++ /dev/null @@ -1,95 +0,0 @@ - -extern crate quickcheck; -extern crate quickchecking; -extern crate rand; - -use quickchecking::fuzzers::{ArrayDimensionC, BaseTypeC, BasicTypeDeclarationC, DeclarationC, - DeclarationListC, FunctionPointerDeclarationC, FunctionPrototypeC, - HeaderC, ParameterC, ParameterListC, PointerLevelC, - StructDeclarationC, TypeQualifierC, UnionDeclarationC}; -use quickcheck::{Arbitrary, StdGen}; -use rand::thread_rng; - -#[test] -fn test_declaraion_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: DeclarationC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_declaraion_list_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: DeclarationListC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_base_type_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: BaseTypeC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_type_qualifier_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: TypeQualifierC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_pointer_level_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: PointerLevelC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_array_dimension_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: ArrayDimensionC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_basic_type_declaration_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: BasicTypeDeclarationC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_struct_declaration_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: StructDeclarationC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_union_declaration_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: UnionDeclarationC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_function_pointer_declaration_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: FunctionPointerDeclarationC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_function_prototype_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: FunctionPrototypeC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_parameter_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: ParameterC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_parameter_list_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: ParameterListC = Arbitrary::arbitrary(gen); -} - -#[test] -fn test_header_c_does_not_panic() { - let ref mut gen = StdGen::new(thread_rng(), 50); - let _: HeaderC = Arbitrary::arbitrary(gen); -} diff --git a/tests/tests.rs b/tests/tests.rs deleted file mode 100644 index 1f116c93b3..0000000000 --- a/tests/tests.rs +++ /dev/null @@ -1,639 +0,0 @@ -extern crate bindgen; -extern crate clap; -extern crate diff; -#[cfg(feature = "logging")] -extern crate env_logger; -extern crate shlex; - -use bindgen::{clang_version, Builder}; -use std::env; -use std::fs; -use std::io::{self, BufRead, BufReader, Error, ErrorKind, Read, Write}; -use std::path::{Path, PathBuf}; -use std::process; -use std::sync::Once; - -#[path = "../src/options.rs"] -mod options; -use crate::options::builder_from_flags; - -mod parse_callbacks; - -// Run `rustfmt` on the given source string and return a tuple of the formatted -// bindings, and rustfmt's stderr. -fn rustfmt(source: String) -> (String, String) { - static CHECK_RUSTFMT: Once = Once::new(); - - CHECK_RUSTFMT.call_once(|| { - if env::var_os("RUSTFMT").is_some() { - return; - } - - let mut rustfmt = { - let mut p = process::Command::new("rustup"); - p.args(&["run", "nightly", "rustfmt", "--version"]); - p - }; - - let have_working_rustfmt = rustfmt - .stdout(process::Stdio::null()) - .stderr(process::Stdio::null()) - .status() - .ok() - .map_or(false, |status| status.success()); - - if !have_working_rustfmt { - panic!( - " -The latest `rustfmt` is required to run the `bindgen` test suite. Install -`rustfmt` with: - - $ rustup update nightly - $ rustup component add rustfmt --toolchain nightly -" - ); - } - }); - - let mut child = match env::var_os("RUSTFMT") { - Some(r) => process::Command::new(r), - None => { - let mut p = process::Command::new("rustup"); - p.args(&["run", "nightly", "rustfmt"]); - p - } - }; - - let mut child = child - .args(&[ - "--config-path", - concat!(env!("CARGO_MANIFEST_DIR"), "/tests/rustfmt.toml"), - ]) - .stdin(process::Stdio::piped()) - .stdout(process::Stdio::piped()) - .stderr(process::Stdio::piped()) - .spawn() - .expect("should spawn `rustup run nightly rustfmt`"); - - let mut stdin = child.stdin.take().unwrap(); - let mut stdout = child.stdout.take().unwrap(); - let mut stderr = child.stderr.take().unwrap(); - - // Write to stdin in a new thread, so that we can read from stdout on this - // thread. This keeps the child from blocking on writing to its stdout which - // might block us from writing to its stdin. - let stdin_handle = - ::std::thread::spawn(move || stdin.write_all(source.as_bytes())); - - // Read stderr on a new thread for similar reasons. - let stderr_handle = ::std::thread::spawn(move || { - let mut output = vec![]; - io::copy(&mut stderr, &mut output) - .map(|_| String::from_utf8_lossy(&output).to_string()) - }); - - let mut output = vec![]; - io::copy(&mut stdout, &mut output).expect("Should copy stdout into vec OK"); - - // Ignore actual rustfmt status because it is often non-zero for trivial - // things. - let _ = child.wait().expect("should wait on rustfmt child OK"); - - stdin_handle - .join() - .expect("writer thread should not have panicked") - .expect("should have written to child rustfmt's stdin OK"); - - let bindings = String::from_utf8(output) - .expect("rustfmt should only emit valid utf-8"); - - let stderr = stderr_handle - .join() - .expect("stderr reader thread should not have panicked") - .expect("should have read child rustfmt's stderr OK"); - - (bindings, stderr) -} - -fn compare_generated_header( - header: &Path, - builder: BuilderState, - check_roundtrip: bool, -) -> Result<(), Error> { - let file_name = header.file_name().ok_or_else(|| { - Error::new(ErrorKind::Other, "compare_generated_header expects a file") - })?; - - let mut expectation = PathBuf::from(header); - expectation.pop(); - expectation.pop(); - expectation.push("expectations"); - expectation.push("tests"); - - let mut looked_at = vec![]; - let mut expectation_file; - - // Try more specific expectations first. - { - let mut expectation = expectation.clone(); - - if cfg!(feature = "testing_only_libclang_9") { - expectation.push("libclang-9"); - } else if cfg!(feature = "testing_only_libclang_5") { - expectation.push("libclang-5"); - } else if cfg!(feature = "testing_only_libclang_4") { - expectation.push("libclang-4"); - } else { - match clang_version().parsed { - None => expectation.push("libclang-9"), - Some(version) => { - let (maj, min) = version; - let version_str = if maj >= 9 { - "9".to_owned() - } else if maj >= 5 { - "5".to_owned() - } else if maj >= 4 { - "4".to_owned() - } else { - format!("{}.{}", maj, min) - }; - expectation.push(format!("libclang-{}", version_str)); - } - } - } - - expectation.push(file_name); - expectation.set_extension("rs"); - expectation_file = fs::File::open(&expectation).ok(); - looked_at.push(expectation); - } - - // Try the default path otherwise. - if expectation_file.is_none() { - expectation.push(file_name); - expectation.set_extension("rs"); - expectation_file = fs::File::open(&expectation).ok(); - looked_at.push(expectation.clone()); - } - - let mut expected = String::new(); - match expectation_file { - Some(f) => { - BufReader::new(f).read_to_string(&mut expected)?; - } - None => panic!( - "missing test expectation file and/or 'testing_only_libclang_$VERSION' \ - feature for header '{}'; looking for expectation file at '{:?}'", - header.display(), - looked_at, - ), - }; - - let (builder, roundtrip_builder) = builder.into_builder(check_roundtrip)?; - - // We skip the generate() error here so we get a full diff below - let (actual, rustfmt_stderr) = match builder.generate() { - Ok(bindings) => { - let actual = bindings.to_string(); - rustfmt(actual) - } - Err(_) => ("".to_string(), "".to_string()), - }; - println!("{}", rustfmt_stderr); - - let (expected, rustfmt_stderr) = rustfmt(expected); - println!("{}", rustfmt_stderr); - - if actual.is_empty() { - return Err(Error::new( - ErrorKind::Other, - "Something's gone really wrong!", - )); - } - - if actual != expected { - println!("{}", rustfmt_stderr); - - println!("diff expected generated"); - println!("--- expected: {:?}", looked_at.last().unwrap()); - println!("+++ generated from: {:?}", header); - - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => println!("-{}", l), - diff::Result::Both(l, _) => println!(" {}", l), - diff::Result::Right(r) => println!("+{}", r), - } - } - - if let Some(var) = env::var_os("BINDGEN_OVERWRITE_EXPECTED") { - if var == "1" { - // Overwrite the expectation with actual output. - let mut expectation_file = - fs::File::create(looked_at.last().unwrap())?; - expectation_file.write_all(actual.as_bytes())?; - } else if var != "0" && var != "" { - panic!("Invalid value of BINDGEN_OVERWRITE_EXPECTED"); - } - } - - if let Some(var) = env::var_os("BINDGEN_TESTS_DIFFTOOL") { - //usecase: var = "meld" -> You can hand check differences - let filename = match header.components().last() { - Some(std::path::Component::Normal(name)) => name, - _ => panic!("Why is the header variable so weird?"), - }; - let actual_result_path = - PathBuf::from(env::var("OUT_DIR").unwrap()).join(filename); - let mut actual_result_file = fs::File::create(&actual_result_path)?; - actual_result_file.write_all(actual.as_bytes())?; - std::process::Command::new(var) - .args(&[looked_at.last().unwrap(), &actual_result_path]) - .output()?; - } - - return Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation or with BINDGEN_TESTS_DIFFTOOL=meld to do this manually.")); - } - - if let Some(roundtrip_builder) = roundtrip_builder { - 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))); - } - } - - Ok(()) -} - -fn builder() -> Builder { - #[cfg(feature = "logging")] - let _ = env_logger::try_init(); - - bindgen::builder().disable_header_comment() -} - -struct BuilderState { - builder: Builder, - parse_callbacks: Option, -} - -impl BuilderState { - fn into_builder( - self, - with_roundtrip_builder: bool, - ) -> Result<(Builder, Option), Error> { - let roundtrip_builder = if with_roundtrip_builder { - let mut flags = self.builder.command_line_flags(); - flags.insert(0, "bindgen".into()); - let mut builder = builder_from_flags(flags.into_iter())?.0; - if let Some(ref parse_cb) = self.parse_callbacks { - builder = - builder.parse_callbacks(parse_callbacks::lookup(parse_cb)); - } - Some(BuilderState { - builder, - parse_callbacks: self.parse_callbacks, - }) - } else { - None - }; - Ok((self.builder, roundtrip_builder)) - } -} - -fn create_bindgen_builder(header: &Path) -> Result { - #[cfg(feature = "logging")] - let _ = env_logger::try_init(); - - let source = fs::File::open(header)?; - let reader = BufReader::new(source); - - // Scoop up bindgen-flags from test header - let mut flags = Vec::with_capacity(2); - let mut parse_callbacks = None; - - for line in reader.lines() { - let line = line?; - if !line.starts_with("// bindgen") { - continue; - } - - if line.contains("bindgen-flags: ") { - let extra_flags = line - .split("bindgen-flags: ") - .last() - .and_then(shlex::split) - .unwrap(); - flags.extend(extra_flags.into_iter()); - } else if line.contains("bindgen-osx-only") { - let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"]; - flags = prepend_flags - .iter() - .map(ToString::to_string) - .chain(flags) - .collect(); - } else if line.contains("bindgen-parse-callbacks: ") { - let parse_cb = - line.split("bindgen-parse-callbacks: ").last().unwrap(); - parse_callbacks = Some(parse_cb.to_owned()); - } - } - - // Different platforms have various different conventions like struct padding, mangling, etc. - // We make the default target as x86_64-unknown-linux - if flags.iter().all(|flag| !flag.starts_with("--target=")) { - if !flags.iter().any(|flag| flag == "--") { - flags.push("--".into()); - } - flags.push("--target=x86_64-unknown-linux".into()); - } - - // Fool builder_from_flags() into believing it has real env::args_os... - // - add "bindgen" as executable name 0th element - // - add header filename as 1st element - // - prepend raw lines so they're in the right order for expected output - // - append the test header's bindgen flags - let header_str = header.to_str().ok_or_else(|| { - Error::new(ErrorKind::Other, "Invalid header file name") - })?; - - let prepend = [ - "bindgen", - // We format in `compare_generated_header` ourselves to have a little - // more control. - "--no-rustfmt-bindings", - "--with-derive-default", - "--disable-header-comment", - "--vtable-generation", - header_str, - "--raw-line", - "", - "--raw-line", - "#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]", - "--raw-line", - "", - ]; - - let args = prepend - .iter() - .map(ToString::to_string) - .chain(flags.into_iter()); - - let mut builder = builder_from_flags(args)?.0; - if let Some(ref parse_cb) = parse_callbacks { - builder = builder.parse_callbacks(parse_callbacks::lookup(parse_cb)); - } - Ok(BuilderState { - builder, - parse_callbacks, - }) -} - -macro_rules! test_header { - ($function:ident, $header:expr) => { - #[test] - fn $function() { - let header = PathBuf::from($header); - let result = create_bindgen_builder(&header).and_then(|builder| { - let check_roundtrip = - env::var_os("BINDGEN_DISABLE_ROUNDTRIP_TEST").is_none(); - compare_generated_header(&header, builder, check_roundtrip) - }); - - if let Err(err) = result { - panic!("{}", err); - } - } - }; -} - -// This file is generated by build.rs -include!(concat!(env!("OUT_DIR"), "/tests.rs")); - -#[test] -fn test_clang_env_args() { - std::env::set_var( - "BINDGEN_EXTRA_CLANG_ARGS", - "-D_ENV_ONE=1 -D_ENV_TWO=\"2 -DNOT_THREE=1\"", - ); - let actual = builder() - .disable_header_comment() - .header_contents( - "test.hpp", - "#ifdef _ENV_ONE\nextern const int x[] = { 42 };\n#endif\n\ - #ifdef _ENV_TWO\nextern const int y[] = { 42 };\n#endif\n\ - #ifdef NOT_THREE\nextern const int z[] = { 42 };\n#endif\n", - ) - .generate() - .unwrap() - .to_string(); - - let (actual, stderr) = rustfmt(actual); - println!("{}", stderr); - - let (expected, _) = rustfmt( - "extern \"C\" { - pub static x: [::std::os::raw::c_int; 1usize]; -} -extern \"C\" { - pub static y: [::std::os::raw::c_int; 1usize]; -} -" - .to_string(), - ); - - assert_eq!(expected, actual); -} - -#[test] -fn test_header_contents() { - let actual = builder() - .disable_header_comment() - .header_contents("test.h", "int foo(const char* a);") - .clang_arg("--target=x86_64-unknown-linux") - .generate() - .unwrap() - .to_string(); - - let (actual, stderr) = rustfmt(actual); - println!("{}", stderr); - - let (expected, _) = rustfmt( - "extern \"C\" { - pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; -} -" - .to_string(), - ); - - assert_eq!(expected, actual); -} - -#[test] -fn test_multiple_header_calls_in_builder() { - let actual = builder() - .header(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/headers/func_ptr.h" - )) - .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h")) - .clang_arg("--target=x86_64-unknown-linux") - .generate() - .unwrap() - .to_string(); - - let (actual, stderr) = rustfmt(actual); - println!("{}", stderr); - - let expected = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs" - )); - let (expected, _) = rustfmt(expected.to_string()); - - if actual != expected { - println!("Generated bindings differ from expected!"); - - for diff in diff::lines(&actual, &expected) { - match diff { - diff::Result::Left(l) => println!("-{}", l), - diff::Result::Both(l, _) => println!(" {}", l), - diff::Result::Right(r) => println!("+{}", r), - } - } - - panic!(); - } -} - -#[test] -fn test_multiple_header_contents() { - let actual = builder() - .header_contents("test.h", "int foo(const char* a);") - .header_contents("test2.h", "float foo2(const char* b);") - .clang_arg("--target=x86_64-unknown-linux") - .generate() - .unwrap() - .to_string(); - - let (actual, stderr) = rustfmt(actual); - println!("{}", stderr); - - let (expected, _) = rustfmt( - "extern \"C\" { - pub fn foo2(b: *const ::std::os::raw::c_char) -> f32; -} -extern \"C\" { - pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; -} -" - .to_string(), - ); - - assert_eq!(expected, actual); -} - -#[test] -fn test_mixed_header_and_header_contents() { - let actual = builder() - .header(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/headers/func_ptr.h" - )) - .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h")) - .header_contents("test.h", "int bar(const char* a);") - .header_contents("test2.h", "float bar2(const char* b);") - .clang_arg("--target=x86_64-unknown-linux") - .generate() - .unwrap() - .to_string(); - - let (actual, stderr) = rustfmt(actual); - println!("{}", stderr); - - let expected = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/test_mixed_header_and_header_contents.rs" - )); - let (expected, _) = rustfmt(expected.to_string()); - - assert_eq!(expected, actual); -} - -#[test] -// Doesn't support executing sh file on Windows. -// We may want to implement it in Rust so that we support all systems. -#[cfg(not(target_os = "windows"))] -fn no_system_header_includes() { - use std::process::Command; - assert!(Command::new("./ci/no-includes.sh") - .current_dir(env!("CARGO_MANIFEST_DIR")) - .spawn() - .expect("should spawn ./ci/no-includes.sh OK") - .wait() - .expect("should wait for ./ci/no-includes OK") - .success()); -} - -#[test] -fn emit_depfile() { - let header = PathBuf::from("tests/headers/enum-default-rust.h"); - let expected_depfile = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests") - .join("expectations") - .join("tests") - .join("enum-default-rust.d"); - let observed_depfile = tempfile::NamedTempFile::new().unwrap(); - let mut builder = create_bindgen_builder(&header).unwrap(); - builder.builder = builder.builder.depfile( - "tests/expectations/tests/enum-default-rust.rs", - observed_depfile.path(), - ); - - let check_roundtrip = - env::var_os("BINDGEN_DISABLE_ROUNDTRIP_TEST").is_none(); - let (builder, _roundtrip_builder) = - 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(); - assert_eq!(observed.trim(), expected.trim()); -} - -#[test] -fn dump_preprocessed_input() { - let arg_keyword = - concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/arg_keyword.hpp"); - let empty_layout = concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/headers/cpp-empty-layout.hpp" - ); - - builder() - .header(arg_keyword) - .header(empty_layout) - .dump_preprocessed_input() - .expect("should dump preprocessed input"); - - fn slurp(p: &str) -> String { - let mut contents = String::new(); - let mut file = fs::File::open(p).unwrap(); - file.read_to_string(&mut contents).unwrap(); - contents - } - - let bindgen_ii = slurp("__bindgen.ii"); - let arg_keyword = slurp(arg_keyword); - let empty_layout = slurp(empty_layout); - - assert!( - bindgen_ii.contains(&arg_keyword), - "arg_keyword.hpp is in the preprocessed file" - ); - assert!( - bindgen_ii.contains(&empty_layout), - "cpp-empty-layout.hpp is in the preprocessed file" - ); -} diff --git a/triagebot.toml b/triagebot.toml new file mode 100644 index 0000000000..77eb2925a3 --- /dev/null +++ b/triagebot.toml @@ -0,0 +1,30 @@ +[relabel] +allow-unauthenticated = [ + "A-*", + "C-*", + "E-*", + "I-*", + "S-*", + "bug", + "dependencies", + "enhancement", + "good first issue", + "hacktoberfest", + "help wanted", + "invalid", + "meta", + "msvc", + "next-release", + "question", + "This Week In Servo (TWiS)", + "windows", +] + +[autolabel."A-C++"] +trigger_files = [ + "**/*.cpp", + "**/*.cc", + "**/*.hpp", +] + +[assign] \ No newline at end of file

( + path: P + ) -> Result + where P: AsRef<::std::ffi::OsStr> { + let library = #library_new?; + #from_library + } + + pub unsafe fn from_library( + library: L + ) -> Result + where L: Into<::libloading::Library> { + let __library = library.into(); + #( #constructor_inits )* + Ok(#lib_ident { + __library, + #( #init_fields ),* + }) + } + + #( #struct_implementation )* + } + } + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn push_func( + &mut self, + ident: &Ident, + symbol: &str, + abi: ClangAbi, + is_variadic: bool, + is_required: bool, + args: &[TokenStream], + args_identifiers: &[TokenStream], + ret: &TokenStream, + ret_ty: &TokenStream, + attributes: &[TokenStream], + ctx: &BindgenContext, + ) { + if !is_variadic { + assert_eq!(args.len(), args_identifiers.len()); + } + + let signature = quote! { unsafe extern #abi fn ( #( #args),* ) #ret }; + let member = if is_required { + signature + } else { + quote! { Result<#signature, ::libloading::Error> } + }; + + self.struct_members.push(quote! { + pub #ident: #member, + }); + + // N.B: If the signature was required, it won't be wrapped in a Result<...> + // and we can simply call it directly. + let fn_ = if is_required { + quote! { self.#ident } + } else { + quote! { self.#ident.as_ref().expect("Expected function, got error.") } + }; + let call_body = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { (#fn_)(#( #args_identifiers ),*) }) + } else { + quote!((#fn_)(#( #args_identifiers ),*) ) + }; + + // We can't implement variadic functions from C easily, so we allow to + // access the function pointer so that the user can call it just fine. + if !is_variadic { + self.struct_implementation.push(quote! { + #(#attributes)* + pub unsafe fn #ident ( &self, #( #args ),* ) #ret_ty { + #call_body + } + }); + } + + // N.B: Unwrap the signature upon construction if it is required to be resolved. + 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(#symbol_cstr) }) + } else { + quote!(__library.get(#symbol_cstr)) + }; + + self.constructor_inits.push(if is_required { + quote! { + let #ident = #library_get.map(|sym| *sym)?; + } + } else { + quote! { + let #ident = #library_get.map(|sym| *sym); + } + }); + + self.init_fields.push(quote! { + #ident + }); + } + + pub fn push_var( + &mut self, + ident: &Ident, + symbol: &str, + ty: &TokenStream, + is_required: bool, + wrap_unsafe_ops: bool, + ) { + let member = if is_required { + quote! { *mut #ty } + } else { + quote! { Result<*mut #ty, ::libloading::Error> } + }; + + self.struct_members.push(quote! { + pub #ident: #member, + }); + + let deref = if is_required { + quote! { self.#ident } + } else { + quote! { *self.#ident.as_ref().expect("Expected variable, got error.") } + }; + self.struct_implementation.push(quote! { + pub unsafe fn #ident (&self) -> *mut #ty { + #deref + } + }); + + 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!(__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 new file mode 100644 index 0000000000..b82ba2aef1 --- /dev/null +++ b/bindgen/codegen/error.rs @@ -0,0 +1,52 @@ +use std::error; +use std::fmt; + +/// Errors that can occur during code generation. +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) enum Error { + /// Tried to generate an opaque blob for a type that did not have a layout. + NoLayoutForOpaqueBlob, + + /// Tried to instantiate an opaque template definition, or a template + /// definition that is too difficult for us to understand (like a partial + /// template specialization). + InstantiationOfOpaqueType, + + /// Function ABI is not supported. + UnsupportedAbi(&'static str), + + /// The pointer type size does not match the target's pointer size. + InvalidPointerSize { + ty_name: String, + ty_size: usize, + ptr_size: usize, + }, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::NoLayoutForOpaqueBlob => { + "Tried to generate an opaque blob, but had no layout.".fmt(f) + } + Error::InstantiationOfOpaqueType => { + "Instantiation of opaque template type or partial template specialization." + .fmt(f) + } + Error::UnsupportedAbi(abi) => { + write!( + f, + "{abi} ABI is not supported by the configured Rust target." + ) + } + Error::InvalidPointerSize { 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}.") + } + } + } +} + +impl error::Error for Error {} + +/// A `Result` of `T` or an error of `bindgen::codegen::error::Error`. +pub(crate) type Result = ::std::result::Result; diff --git a/bindgen/codegen/helpers.rs b/bindgen/codegen/helpers.rs new file mode 100644 index 0000000000..9b86ba47b0 --- /dev/null +++ b/bindgen/codegen/helpers.rs @@ -0,0 +1,358 @@ +//! Helpers for code generation that don't need macro expansion. + +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}; + use std::{borrow::Cow, str::FromStr}; + + pub(crate) fn repr(which: &str) -> TokenStream { + let which = Ident::new(which, Span::call_site()); + quote! { + #[repr( #which )] + } + } + + pub(crate) fn repr_list(which_ones: &[&str]) -> TokenStream { + let which_ones = which_ones + .iter() + .map(|one| TokenStream::from_str(one).expect("repr to be valid")); + quote! { + #[repr( #( #which_ones ),* )] + } + } + + pub(crate) fn derives(which_ones: &[&str]) -> TokenStream { + let which_ones = which_ones + .iter() + .map(|one| TokenStream::from_str(one).expect("derive to be valid")); + quote! { + #[derive( #( #which_ones ),* )] + } + } + + pub(crate) fn inline() -> TokenStream { + quote! { + #[inline] + } + } + + pub(crate) fn must_use() -> TokenStream { + quote! { + #[must_use] + } + } + + pub(crate) fn non_exhaustive() -> TokenStream { + quote! { + #[non_exhaustive] + } + } + + pub(crate) fn doc(comment: &str) -> TokenStream { + if comment.is_empty() { + quote!() + } else { + quote!(#[doc = #comment]) + } + } + + pub(crate) fn link_name(name: &str) -> TokenStream { + // LLVM mangles the name by default but it's already mangled. + // Prefixing the name with \u{1} should tell LLVM to not mangle it. + let name: Cow<'_, str> = if MANGLE { + name.into() + } else { + format!("\u{1}{name}").into() + }; + + quote! { + #[link_name = #name] + } + } +} + +/// 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]> } + } + }; + } + + 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! { #ident<[u8; #size]> } + } +} + +/// Integer type of the same size as the given `Layout`. +pub(crate) fn integer_type(layout: Layout) -> Option { + Layout::known_type_for_size(layout.size) +} + +pub(crate) const BITFIELD_UNIT: &str = "__BindgenBitfieldUnit"; + +/// Generates a bitfield allocation unit type for a type with the given `Layout`. +pub(crate) fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> syn::Type { + let size = layout.size; + let bitfield_unit_name = Ident::new(BITFIELD_UNIT, Span::call_site()); + let ty = syn::parse_quote! { #bitfield_unit_name<[u8; #size]> }; + + if ctx.options().enable_cxx_namespaces { + return syn::parse_quote! { root::#ty }; + } + + ty +} + +pub(crate) mod ast_ty { + use crate::ir::context::BindgenContext; + use crate::ir::function::FunctionSig; + use crate::ir::layout::Layout; + use crate::ir::ty::{FloatKind, IntKind}; + use proc_macro2::TokenStream; + use std::str::FromStr; + + pub(crate) fn c_void(ctx: &BindgenContext) -> syn::Type { + // ctypes_prefix takes precedence + match ctx.options().ctypes_prefix { + Some(ref prefix) => { + let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); + syn::parse_quote! { #prefix::c_void } + } + None => { + if ctx.options().use_core { + syn::parse_quote! { ::core::ffi::c_void } + } else { + syn::parse_quote! { ::std::os::raw::c_void } + } + } + } + } + + pub(crate) fn raw_type(ctx: &BindgenContext, name: &str) -> syn::Type { + let ident = ctx.rust_ident_raw(name); + match ctx.options().ctypes_prefix { + Some(ref prefix) => { + let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); + syn::parse_quote! { #prefix::#ident } + } + None => { + if ctx.options().use_core && + ctx.options().rust_features().core_ffi_c + { + syn::parse_quote! { ::core::ffi::#ident } + } else { + syn::parse_quote! { ::std::os::raw::#ident } + } + } + } + } + + pub(crate) fn int_kind_rust_type( + ctx: &BindgenContext, + ik: IntKind, + layout: Option, + ) -> syn::Type { + 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"), + IntKind::UShort => raw_type(ctx, "c_ushort"), + IntKind::Int => raw_type(ctx, "c_int"), + IntKind::UInt => raw_type(ctx, "c_uint"), + IntKind::Long => raw_type(ctx, "c_long"), + IntKind::ULong => raw_type(ctx, "c_ulong"), + IntKind::LongLong => raw_type(ctx, "c_longlong"), + IntKind::ULongLong => raw_type(ctx, "c_ulonglong"), + IntKind::WChar => { + let layout = + layout.expect("Couldn't compute wchar_t's layout?"); + Layout::known_type_for_size(layout.size) + .expect("Non-representable wchar_t?") + } + + IntKind::I8 => syn::parse_quote! { i8 }, + IntKind::U8 => syn::parse_quote! { u8 }, + IntKind::I16 => syn::parse_quote! { i16 }, + IntKind::U16 => syn::parse_quote! { u16 }, + IntKind::I32 => syn::parse_quote! { i32 }, + IntKind::U32 => syn::parse_quote! { u32 }, + IntKind::I64 => syn::parse_quote! { i64 }, + IntKind::U64 => syn::parse_quote! { u64 }, + IntKind::Custom { name, .. } => { + syn::parse_str(name).expect("Invalid integer type.") + } + IntKind::U128 => { + if true { + syn::parse_quote! { u128 } + } else { + // Best effort thing, but wrong alignment + // unfortunately. + syn::parse_quote! { [u64; 2] } + } + } + IntKind::I128 => { + if true { + syn::parse_quote! { i128 } + } else { + syn::parse_quote! { [u64; 2] } + } + } + } + } + + pub(crate) fn float_kind_rust_type( + ctx: &BindgenContext, + fk: FloatKind, + layout: Option, + ) -> syn::Type { + // TODO: we probably should take the type layout into account more + // often? + // + // Also, maybe this one shouldn't be the default? + match (fk, ctx.options().convert_floats) { + (FloatKind::Float16, _) => { + // TODO: do f16 when rust lands it + ctx.generated_bindgen_float16(); + if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::__BindgenFloat16 } + } else { + syn::parse_quote! { __BindgenFloat16 } + } + } + (FloatKind::Float, true) => syn::parse_quote! { f32 }, + (FloatKind::Double, true) => syn::parse_quote! { f64 }, + (FloatKind::Float, false) => raw_type(ctx, "c_float"), + (FloatKind::Double, false) => raw_type(ctx, "c_double"), + (FloatKind::LongDouble, _) => { + 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 true { + syn::parse_quote! { u128 } + } else { + syn::parse_quote! { [u64; 2] } + } + } + } + } + + pub(crate) fn int_expr(val: i64) -> TokenStream { + // Don't use quote! { #val } because that adds the type suffix. + let val = proc_macro2::Literal::i64_unsuffixed(val); + quote!(#val) + } + + pub(crate) fn uint_expr(val: u64) -> TokenStream { + // Don't use quote! { #val } because that adds the type suffix. + let val = proc_macro2::Literal::u64_unsuffixed(val); + quote!(#val) + } + + pub(crate) fn cstr_expr(mut string: String) -> TokenStream { + string.push('\0'); + let b = proc_macro2::Literal::byte_string(string.as_bytes()); + quote! { + #b + } + } + + pub(crate) fn float_expr(f: f64) -> Result { + if f.is_finite() { + let val = proc_macro2::Literal::f64_unsuffixed(f); + + return Ok(quote!(#val)); + } + + if f.is_nan() { + return Ok(quote! { f64::NAN as _ }); + } + + if f.is_infinite() { + let tokens = if f.is_sign_positive() { + quote! { f64::INFINITY as _ } + } else { + quote! { f64::NEG_INFINITY as _ } + }; + return Ok(tokens); + } + + warn!("Unknown non-finite float number: {f:?}"); + Err(()) + } + + pub(crate) fn arguments_from_signature( + signature: &FunctionSig, + ctx: &BindgenContext, + ) -> Vec { + let mut unnamed_arguments = 0; + signature + .argument_types() + .iter() + .map(|&(ref name, _ty)| { + let name = if let Some(ref name) = *name { + ctx.rust_ident(name) + } else { + unnamed_arguments += 1; + ctx.rust_ident(format!("arg{unnamed_arguments}")) + }; + quote! { #name } + }) + .collect() + } +} diff --git a/bindgen/codegen/impl_debug.rs b/bindgen/codegen/impl_debug.rs new file mode 100644 index 0000000000..45394724de --- /dev/null +++ b/bindgen/codegen/impl_debug.rs @@ -0,0 +1,220 @@ +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; +use std::fmt::Write as _; + +pub(crate) fn gen_debug_impl( + ctx: &BindgenContext, + fields: &[Field], + item: &Item, + kind: CompKind, +) -> proc_macro2::TokenStream { + let struct_name = item.canonical_name(ctx); + let mut format_string = format!("{struct_name} {{{{ "); + let mut tokens = vec![]; + + if item.is_opaque(ctx, &()) { + format_string.push_str("opaque"); + } else { + match kind { + CompKind::Union => { + format_string.push_str("union"); + } + CompKind::Struct => { + let processed_fields = fields.iter().filter_map(|f| match f { + Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), + Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), + }); + + for (i, (fstring, toks)) in processed_fields.enumerate() { + if i > 0 { + format_string.push_str(", "); + } + tokens.extend(toks); + format_string.push_str(&fstring); + } + } + } + } + + format_string.push_str(" }}"); + tokens.insert(0, quote! { #format_string }); + + let prefix = ctx.trait_prefix(); + + quote! { + fn fmt(&self, f: &mut ::#prefix::fmt::Formatter<'_>) -> ::#prefix ::fmt::Result { + write!(f, #( #tokens ),*) + } + } +} + +/// A trait for the things which we can codegen tokens that contribute towards a +/// generated `impl Debug`. +pub(crate) trait ImplDebug<'a> { + /// Any extra parameter required by this a particular `ImplDebug` implementation. + type Extra; + + /// Generate a format string snippet to be included in the larger `impl Debug` + /// format string, and the code to get the format string's interpolation values. + fn impl_debug( + &self, + ctx: &BindgenContext, + extra: Self::Extra, + ) -> Option<(String, Vec)>; +} + +impl ImplDebug<'_> for FieldData { + type Extra = (); + + fn impl_debug( + &self, + ctx: &BindgenContext, + _: Self::Extra, + ) -> Option<(String, Vec)> { + if let Some(name) = self.name() { + ctx.resolve_item(self.ty()).impl_debug(ctx, name) + } else { + None + } + } +} + +impl ImplDebug<'_> for BitfieldUnit { + type Extra = (); + + fn impl_debug( + &self, + ctx: &BindgenContext, + _: Self::Extra, + ) -> Option<(String, Vec)> { + let mut format_string = String::new(); + let mut tokens = vec![]; + for (i, bitfield) in self.bitfields().iter().enumerate() { + if i > 0 { + format_string.push_str(", "); + } + + if let Some(bitfield_name) = 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! { + self.#name_ident () + }); + } + } + + Some((format_string, tokens)) + } +} + +impl<'a> ImplDebug<'a> for Item { + type Extra = &'a str; + + fn impl_debug( + &self, + ctx: &BindgenContext, + name: &str, + ) -> Option<(String, Vec)> { + let name_ident = ctx.rust_ident(name); + + // We don't know if blocklisted items `impl Debug` or not, so we can't + // add them to the format string we're building up. + if !ctx.allowlisted_items().contains(&self.id()) { + return None; + } + + let ty = self.as_type()?; + + fn debug_print( + name: &str, + name_ident: &proc_macro2::TokenStream, + ) -> Option<(String, Vec)> { + Some(( + format!("{name}: {{:?}}"), + vec![quote! { + self.#name_ident + }], + )) + } + + match *ty.kind() { + // Handle the simple cases. + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Function(..) | + TypeKind::Enum(..) | + TypeKind::Reference(..) | + TypeKind::UnresolvedTypeRef(..) | + TypeKind::ObjCInterface(..) | + TypeKind::ObjCId | + TypeKind::Comp(..) | + TypeKind::ObjCSel => debug_print(name, "e! { #name_ident }), + + TypeKind::TemplateInstantiation(ref inst) => { + if inst.is_opaque(ctx, self) { + Some((format!("{name}: opaque"), vec![])) + } else { + 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!("{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!("{name}: Array with length {len}"), vec![])) + } else { + // 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![])) + } else { + let self_ids = 0..len; + Some(( + format!("{name}({{}})"), + vec![quote! { + #(format!("{:?}", self.#self_ids)),* + }], + )) + } + } + + TypeKind::ResolvedTypeRef(t) | + TypeKind::TemplateAlias(t, _) | + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { + // We follow the aliases + ctx.resolve_item(t).impl_debug(ctx, name) + } + + TypeKind::Pointer(inner) => { + let inner_type = ctx.resolve_type(inner).canonical_type(ctx); + match *inner_type.kind() { + TypeKind::Function(ref sig) + if !sig.function_pointers_can_derive() => + { + Some((format!("{name}: FunctionPointer"), vec![])) + } + _ => debug_print(name, "e! { #name_ident }), + } + } + + TypeKind::Opaque => None, + } + } +} diff --git a/bindgen/codegen/impl_partialeq.rs b/bindgen/codegen/impl_partialeq.rs new file mode 100644 index 0000000000..a8edb4773d --- /dev/null +++ b/bindgen/codegen/impl_partialeq.rs @@ -0,0 +1,114 @@ +use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods}; +use crate::ir::context::BindgenContext; +use crate::ir::item::{IsOpaque, Item}; +use crate::ir::ty::TypeKind; + +/// Generate a manual implementation of `PartialEq` trait for the +/// specified compound type. +pub(crate) fn gen_partialeq_impl( + ctx: &BindgenContext, + comp_info: &CompInfo, + item: &Item, + ty_for_impl: &proc_macro2::TokenStream, +) -> Option { + let mut tokens = vec![]; + + if item.is_opaque(ctx, &()) { + tokens.push(quote! { + &self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..] + }); + } else if comp_info.kind() == CompKind::Union { + assert!(!ctx.options().untagged_union); + tokens.push(quote! { + &self.bindgen_union_field[..] == &other.bindgen_union_field[..] + }); + } else { + 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; + tokens.push(gen_field(ctx, ty_item, field_name)); + } + + for field in comp_info.fields() { + match *field { + Field::DataMember(ref fd) => { + let ty_item = ctx.resolve_item(fd.ty()); + let name = fd.name().unwrap(); + tokens.push(gen_field(ctx, ty_item, name)); + } + Field::Bitfields(ref bu) => { + for bitfield in bu.bitfields() { + if bitfield.name().is_some() { + let getter_name = bitfield.getter_name(); + let name_ident = ctx.rust_ident_raw(getter_name); + tokens.push(quote! { + self.#name_ident () == other.#name_ident () + }); + } + } + } + } + } + } + + Some(quote! { + fn eq(&self, other: & #ty_for_impl) -> bool { + #( #tokens )&&* + } + }) +} + +fn gen_field( + ctx: &BindgenContext, + ty_item: &Item, + name: &str, +) -> proc_macro2::TokenStream { + fn quote_equals( + name_ident: &proc_macro2::Ident, + ) -> proc_macro2::TokenStream { + quote! { self.#name_ident == other.#name_ident } + } + + let name_ident = ctx.rust_ident(name); + let ty = ty_item.expect_type(); + + match *ty.kind() { + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Complex(..) | + TypeKind::Float(..) | + TypeKind::Enum(..) | + TypeKind::TypeParam | + TypeKind::UnresolvedTypeRef(..) | + TypeKind::Reference(..) | + TypeKind::ObjCInterface(..) | + TypeKind::ObjCId | + TypeKind::ObjCSel | + TypeKind::Comp(..) | + TypeKind::Pointer(_) | + TypeKind::Function(..) | + TypeKind::Array(..) | + TypeKind::TemplateInstantiation(..) | + TypeKind::Opaque => quote_equals(&name_ident), + TypeKind::Vector(_, len) => { + let self_ids = 0..len; + let other_ids = 0..len; + quote! { + #(self.#self_ids == other.#other_ids &&)* true + } + } + + TypeKind::ResolvedTypeRef(t) | + TypeKind::TemplateAlias(t, _) | + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { + let inner_item = ctx.resolve_item(t); + gen_field(ctx, inner_item, name) + } + } +} diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs new file mode 100644 index 0000000000..48b1518445 --- /dev/null +++ b/bindgen/codegen/mod.rs @@ -0,0 +1,5971 @@ +mod dyngen; +pub(crate) mod error; + +mod helpers; +mod impl_debug; +mod impl_partialeq; +mod postprocessing; +mod serialize; +pub(crate) mod struct_layout; + +#[cfg(test)] +#[allow(warnings)] +pub(crate) mod bitfield_unit; +#[cfg(all(test, target_endian = "little"))] +mod bitfield_unit_tests; + +use self::dyngen::DynamicItems; +use self::helpers::attributes; +use self::struct_layout::StructLayoutTracker; + +use super::BindgenOptions; + +use crate::callbacks::{ + AttributeInfo, DeriveInfo, DiscoveredItem, DiscoveredItemId, FieldInfo, + TypeKind as DeriveTypeKind, +}; +use crate::codegen::error::Error; +use crate::ir::analysis::{HasVtable, Sizedness}; +use crate::ir::annotations::{ + Annotations, FieldAccessorKind, FieldVisibilityKind, +}; +use crate::ir::comp::{ + Bitfield, BitfieldUnit, CompInfo, CompKind, Field, FieldData, FieldMethods, + Method, MethodKind, +}; +use crate::ir::context::{BindgenContext, ItemId}; +use crate::ir::derive::{ + CanDerive, CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq, + CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd, +}; +use crate::ir::dot; +use crate::ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; +use crate::ir::function::{ + ClangAbi, Function, FunctionKind, FunctionSig, Linkage, +}; +use crate::ir::int::IntKind; +use crate::ir::item::{IsOpaque, Item, ItemCanonicalName, ItemCanonicalPath}; +use crate::ir::item_kind::ItemKind; +use crate::ir::layout::Layout; +use crate::ir::module::Module; +use crate::ir::objc::{ObjCInterface, ObjCMethod}; +use crate::ir::template::{ + AsTemplateParam, TemplateInstantiation, TemplateParameters, +}; +use crate::ir::ty::{Type, TypeKind}; +use crate::ir::var::Var; + +use proc_macro2::{Ident, Span}; +use quote::{ToTokens, TokenStreamExt}; + +use crate::{Entry, HashMap, HashSet}; +use std::borrow::Cow; +use std::cell::Cell; +use std::collections::VecDeque; +use std::ffi::CStr; +use std::fmt::{self, Write}; +use std::ops; +use std::str::{self, FromStr}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum CodegenError { + Serialize { msg: String, loc: String }, + Io(String), +} + +impl From for CodegenError { + fn from(err: std::io::Error) -> Self { + Self::Io(err.to_string()) + } +} + +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}") + } + Self::Io(err) => err.fmt(f), + } + } +} + +// Name of type defined in constified enum module +pub(crate) static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type"; + +fn top_level_path( + ctx: &BindgenContext, + item: &Item, +) -> Vec { + let mut path = vec![quote! { self }]; + + if ctx.options().enable_cxx_namespaces { + for _ in 0..item.codegen_depth(ctx) { + path.push(quote! { super }); + } + } + + path +} + +fn root_import( + ctx: &BindgenContext, + module: &Item, +) -> proc_macro2::TokenStream { + assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up"); + assert!(module.is_module()); + + let mut path = top_level_path(ctx, module); + + let root = ctx.root_module().canonical_name(ctx); + let root_ident = ctx.rust_ident(root); + path.push(quote! { #root_ident }); + + let mut tokens = quote! {}; + tokens.append_separated(path, quote!(::)); + + quote! { + #[allow(unused_imports)] + use #tokens ; + } +} + +bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + struct DerivableTraits: u16 { + const DEBUG = 1 << 0; + const DEFAULT = 1 << 1; + const COPY = 1 << 2; + const CLONE = 1 << 3; + const HASH = 1 << 4; + const PARTIAL_ORD = 1 << 5; + const ORD = 1 << 6; + const PARTIAL_EQ = 1 << 7; + const EQ = 1 << 8; + } +} + +fn derives_of_item( + item: &Item, + ctx: &BindgenContext, + packed: bool, +) -> DerivableTraits { + let mut derivable_traits = DerivableTraits::empty(); + + if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { + derivable_traits |= DerivableTraits::COPY; + + // 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. + return derivable_traits; + } + + if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() { + derivable_traits |= DerivableTraits::DEBUG; + } + + if item.can_derive_default(ctx) && !item.annotations().disallow_default() { + derivable_traits |= DerivableTraits::DEFAULT; + } + + if item.can_derive_hash(ctx) { + derivable_traits |= DerivableTraits::HASH; + } + + if item.can_derive_partialord(ctx) { + derivable_traits |= DerivableTraits::PARTIAL_ORD; + } + + if item.can_derive_ord(ctx) { + derivable_traits |= DerivableTraits::ORD; + } + + if item.can_derive_partialeq(ctx) { + derivable_traits |= DerivableTraits::PARTIAL_EQ; + } + + if item.can_derive_eq(ctx) { + derivable_traits |= DerivableTraits::EQ; + } + + 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> { + [ + (DerivableTraits::DEBUG, "Debug"), + (DerivableTraits::DEFAULT, "Default"), + (DerivableTraits::COPY, "Copy"), + (DerivableTraits::CLONE, "Clone"), + (DerivableTraits::HASH, "Hash"), + (DerivableTraits::PARTIAL_ORD, "PartialOrd"), + (DerivableTraits::ORD, "Ord"), + (DerivableTraits::PARTIAL_EQ, "PartialEq"), + (DerivableTraits::EQ, "Eq"), + ] + .iter() + .filter_map(|&(flag, derive)| { + Some(derive).filter(|_| derivable_traits.contains(flag)) + }) + .collect() + } +} + +struct WrapAsVariadic { + new_name: String, + idx_of_va_list_arg: usize, +} + +struct CodegenResult<'a> { + items: Vec, + dynamic_items: DynamicItems, + + /// A monotonic counter used to add stable unique ID's to stuff that doesn't + /// need to be referenced by anything. + codegen_id: &'a Cell, + + /// Whether a bindgen union has been generated at least once. + saw_bindgen_union: bool, + + /// Whether an incomplete array has been generated at least once. + saw_incomplete_array: bool, + + /// Whether Objective C types have been seen at least once. + saw_objc: bool, + + /// Whether Apple block types have been seen at least once. + saw_block: bool, + + /// Whether a bitfield allocation unit has been seen at least once. + saw_bitfield_unit: bool, + + items_seen: HashSet, + /// The set of generated function/var names, needed because in C/C++ is + /// legal to do something like: + /// + /// ```c++ + /// extern "C" { + /// void foo(); + /// extern int bar; + /// } + /// + /// extern "C" { + /// void foo(); + /// extern int bar; + /// } + /// ``` + /// + /// Being these two different declarations. + functions_seen: HashSet, + vars_seen: HashSet, + + /// Used for making bindings to overloaded functions. Maps from a canonical + /// function name to the number of overloads we have already codegen'd for + /// that name. This lets us give each overload a unique suffix. + overload_counters: HashMap, + + /// List of items to serialize. With optionally the argument for the wrap as + /// variadic transformation to be applied. + items_to_serialize: Vec<(ItemId, Option)>, +} + +impl<'a> CodegenResult<'a> { + fn new(codegen_id: &'a Cell) -> Self { + CodegenResult { + items: vec![], + dynamic_items: DynamicItems::new(), + saw_bindgen_union: false, + saw_incomplete_array: false, + saw_objc: false, + saw_block: false, + saw_bitfield_unit: false, + codegen_id, + items_seen: Default::default(), + functions_seen: Default::default(), + vars_seen: Default::default(), + overload_counters: Default::default(), + items_to_serialize: Default::default(), + } + } + + fn dynamic_items(&mut self) -> &mut DynamicItems { + &mut self.dynamic_items + } + + fn saw_bindgen_union(&mut self) { + self.saw_bindgen_union = true; + } + + fn saw_incomplete_array(&mut self) { + self.saw_incomplete_array = true; + } + + fn saw_objc(&mut self) { + self.saw_objc = true; + } + + fn saw_block(&mut self) { + self.saw_block = true; + } + + fn saw_bitfield_unit(&mut self) { + self.saw_bitfield_unit = true; + } + + fn seen>(&self, item: Id) -> bool { + self.items_seen.contains(&item.into()) + } + + fn set_seen>(&mut self, item: Id) { + self.items_seen.insert(item.into()); + } + + fn seen_function(&self, name: &str) -> bool { + self.functions_seen.contains(name) + } + + fn saw_function(&mut self, name: &str) { + self.functions_seen.insert(name.into()); + } + + /// Get the overload number for the given function name. Increments the + /// counter internally so the next time we ask for the overload for this + /// name, we get the incremented value, and so on. + fn overload_number(&mut self, name: &str) -> u32 { + let counter = self.overload_counters.entry(name.into()).or_insert(0); + let number = *counter; + *counter += 1; + number + } + + fn seen_var(&self, name: &str) -> bool { + self.vars_seen.contains(name) + } + + fn saw_var(&mut self, name: &str) { + self.vars_seen.insert(name.into()); + } + + fn inner(&mut self, cb: F) -> Vec + where + F: FnOnce(&mut Self), + { + let mut new = Self::new(self.codegen_id); + + cb(&mut new); + + self.saw_incomplete_array |= new.saw_incomplete_array; + self.saw_objc |= new.saw_objc; + self.saw_block |= new.saw_block; + self.saw_bitfield_unit |= new.saw_bitfield_unit; + self.saw_bindgen_union |= new.saw_bindgen_union; + + new.items + } +} + +impl ops::Deref for CodegenResult<'_> { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl ops::DerefMut for CodegenResult<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +/// A trait to convert a rust type into a pointer, optionally const, to the same +/// type. +trait ToPtr { + fn to_ptr(self, is_const: bool) -> syn::Type; +} + +impl ToPtr for syn::Type { + fn to_ptr(self, is_const: bool) -> syn::Type { + if is_const { + syn::parse_quote! { *const #self } + } else { + syn::parse_quote! { *mut #self } + } + } +} + +/// An extension trait for `syn::Type` that lets us append any implicit +/// template parameters that exist for some type, if necessary. +trait WithImplicitTemplateParams { + fn with_implicit_template_params( + self, + ctx: &BindgenContext, + item: &Item, + ) -> Self; +} + +impl WithImplicitTemplateParams for syn::Type { + fn with_implicit_template_params( + self, + ctx: &BindgenContext, + item: &Item, + ) -> Self { + let item = item.id().into_resolver().through_type_refs().resolve(ctx); + + let params = match *item.expect_type().kind() { + TypeKind::UnresolvedTypeRef(..) => { + unreachable!("already resolved unresolved type refs") + } + TypeKind::ResolvedTypeRef(..) => { + unreachable!("we resolved item through type refs") + } + // None of these types ever have implicit template parameters. + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Pointer(..) | + TypeKind::Reference(..) | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Array(..) | + TypeKind::TypeParam | + TypeKind::Opaque | + TypeKind::Function(..) | + TypeKind::Enum(..) | + TypeKind::ObjCId | + TypeKind::ObjCSel | + TypeKind::TemplateInstantiation(..) => None, + _ => { + let params = item.used_template_params(ctx); + if params.is_empty() { + None + } else { + Some(params.into_iter().map(|p| { + p.try_to_rust_ty(ctx, &()).expect( + "template params cannot fail to be a rust type", + ) + })) + } + } + }; + + if let Some(params) = params { + syn::parse_quote! { #self<#(#params),*> } + } else { + self + } + } +} + +trait CodeGenerator { + /// Extra information from the caller. + type Extra; + + /// Extra information returned to the caller. + type Return; + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + extra: &Self::Extra, + ) -> Self::Return; +} + +impl Item { + fn process_before_codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult, + ) -> bool { + if !self.is_enabled_for_codegen(ctx) { + return false; + } + + if self.is_blocklisted(ctx) || result.seen(self.id()) { + debug!( + "::process_before_codegen: Ignoring hidden or seen: \ + self = {self:?}" + ); + return false; + } + + if !ctx.codegen_items().contains(&self.id()) { + // 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:?}"); + } + + result.set_seen(self.id()); + true + } +} + +impl CodeGenerator for Item { + type Extra = (); + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + _extra: &(), + ) { + debug!("::codegen: self = {self:?}"); + if !self.process_before_codegen(ctx, result) { + return; + } + + match *self.kind() { + ItemKind::Module(ref module) => { + module.codegen(ctx, result, self); + } + ItemKind::Function(ref fun) => { + fun.codegen(ctx, result, self); + } + ItemKind::Var(ref var) => { + var.codegen(ctx, result, self); + } + ItemKind::Type(ref ty) => { + ty.codegen(ctx, result, self); + } + } + } +} + +impl CodeGenerator for Module { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + debug!("::codegen: item = {item:?}"); + + let codegen_self = |result: &mut CodegenResult, + found_any: &mut bool| { + for child in self.children() { + if ctx.codegen_items().contains(child) { + *found_any = true; + ctx.resolve_item(*child).codegen(ctx, result, &()); + } + } + + if item.id() == ctx.root_module() { + if result.saw_block { + utils::prepend_block_header(ctx, &mut *result); + } + if result.saw_bindgen_union { + utils::prepend_union_types(ctx, &mut *result); + } + if result.saw_incomplete_array { + utils::prepend_incomplete_array_types(ctx, &mut *result); + } + if ctx.need_bindgen_float16_type() { + utils::prepend_float16_type(&mut *result); + } + 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); + } + if result.saw_bitfield_unit { + utils::prepend_bitfield_unit_type(ctx, &mut *result); + } + } + }; + + if !ctx.options().enable_cxx_namespaces || + (self.is_inline() && + !ctx.options().conservative_inline_namespaces) + { + codegen_self(result, &mut false); + return; + } + + let mut found_any = false; + let inner_items = result.inner(|result| { + result.push(root_import(ctx, item)); + + let path = item + .namespace_aware_canonical_path(ctx) + .join("::") + .into_boxed_str(); + if let Some(raw_lines) = ctx.options().module_lines.get(&path) { + for raw_line in raw_lines { + found_any = true; + result.push( + proc_macro2::TokenStream::from_str(raw_line).unwrap(), + ); + } + } + + codegen_self(result, &mut found_any); + }); + + // Don't bother creating an empty module. + if !found_any { + return; + } + + let name = item.canonical_name(ctx); + let ident = ctx.rust_ident(name); + result.push(if item.id() == ctx.root_module() { + quote! { + #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] + pub mod #ident { + #( #inner_items )* + } + } + } else { + quote! { + pub mod #ident { + #( #inner_items )* + } + } + }); + } +} + +impl CodeGenerator for Var { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + use crate::ir::var::VarType; + debug!("::codegen: item = {item:?}"); + debug_assert!(item.is_enabled_for_codegen(ctx)); + + let canonical_name = item.canonical_name(ctx); + + if result.seen_var(&canonical_name) { + return; + } + result.saw_var(&canonical_name); + + let canonical_ident = ctx.rust_ident(&canonical_name); + + // We can't generate bindings to static variables of templates. The + // number of actual variables for a single declaration are open ended + // and we don't know what instantiations do or don't exist. + if !item.all_template_params(ctx).is_empty() { + return; + } + + let mut attrs = vec![]; + if let Some(comment) = item.comment(ctx) { + 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() { + let const_expr = match *val { + VarType::Bool(val) => Some(val.to_token_stream()), + VarType::Int(val) => { + let int_kind = var_ty + .into_resolver() + .through_type_aliases() + .through_type_refs() + .resolve(ctx) + .expect_type() + .as_integer() + .unwrap(); + let val = if int_kind.is_signed() { + helpers::ast_ty::int_expr(val) + } else { + helpers::ast_ty::uint_expr(val as _) + }; + Some(val) + } + VarType::String(ref bytes) => { + let prefix = ctx.trait_prefix(); + + let options = ctx.options(); + let rust_features = options.rust_features; + + let mut cstr_bytes = bytes.clone(); + cstr_bytes.push(0); + let len = proc_macro2::Literal::usize_unsuffixed( + cstr_bytes.len(), + ); + 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 { + 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) + }; + }); + } + } 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) => 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 { + 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( + &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! {} + } else { + quote! { mut } + }; + + let safety = ctx + .options() + .rust_features + .unsafe_extern_blocks + .then(|| quote!(unsafe)); + + let tokens = quote!( + #safety extern "C" { + #(#attrs)* + pub static #maybe_mut #canonical_ident: #ty; + } + ); + + if ctx.options().dynamic_library_name.is_some() { + result.dynamic_items().push_var( + &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); + } + } + } +} + +impl CodeGenerator for Type { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + debug!("::codegen: item = {item:?}"); + debug_assert!(item.is_enabled_for_codegen(ctx)); + + match *self.kind() { + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Array(..) | + TypeKind::Vector(..) | + TypeKind::Pointer(..) | + TypeKind::Reference(..) | + TypeKind::Function(..) | + TypeKind::ResolvedTypeRef(..) | + TypeKind::Opaque | + TypeKind::TypeParam => { + // These items don't need code generation, they only need to be + // converted to rust types in fields, arguments, and such. + // NOTE(emilio): If you add to this list, make sure to also add + // it to BindgenContext::compute_allowlisted_and_codegen_items. + } + TypeKind::TemplateInstantiation(ref inst) => { + inst.codegen(ctx, result, item); + } + TypeKind::BlockPointer(inner) => { + if !ctx.options().generate_block { + return; + } + + let inner_item = + inner.into_resolver().through_type_refs().resolve(ctx); + let name = item.canonical_name(ctx); + + let inner_rust_type = { + if let TypeKind::Function(fnsig) = + inner_item.kind().expect_type().kind() + { + utils::fnsig_block(ctx, fnsig) + } else { + 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) + } else { + quote! {} + }; + + tokens.append_all(quote! { + pub type #rust_name = #inner_rust_type ; + }); + + result.push(tokens); + result.saw_block(); + } + TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item), + TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => { + let inner_item = + inner.into_resolver().through_type_refs().resolve(ctx); + let name = item.canonical_name(ctx); + let path = item.canonical_path(ctx); + + { + let through_type_aliases = inner + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(ctx); + + // Try to catch the common pattern: + // + // typedef struct foo { ... } foo; + // + // here, and also other more complex cases like #946. + if through_type_aliases.canonical_path(ctx) == path { + return; + } + } + + // If this is a known named type, disallow generating anything + // for it too. If size_t -> usize conversions are enabled, we + // need to check that these conversions are permissible, but + // nothing needs to be generated, still. + let spelling = self.name().expect("Unnamed alias?"); + if utils::type_from_named(ctx, spelling).is_some() { + if let "size_t" | "ssize_t" = spelling { + let layout = inner_item + .kind() + .expect_type() + .layout(ctx) + .expect("No layout?"); + assert_eq!( + layout.size, + ctx.target_pointer_size(), + "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 `{spelling}` ({}) does not match the target pointer size ({})", + layout.align, + ctx.target_pointer_size(), + ); + } + return; + } + + let mut outer_params = item.used_template_params(ctx); + + let is_opaque = item.is_opaque(ctx, &()); + let inner_rust_type = if is_opaque { + outer_params = vec![]; + self.to_opaque(ctx, item) + } else { + // Its possible that we have better layout information than + // the inner type does, so fall back to an opaque blob based + // on our layout if converting the inner item fails. + inner_item + .try_to_rust_ty_or_opaque(ctx, &()) + .unwrap_or_else(|_| self.to_opaque(ctx, item)) + .with_implicit_template_params(ctx, inner_item) + }; + + { + // FIXME(emilio): This is a workaround to avoid generating + // incorrect type aliases because of types that we haven't + // been able to resolve (because, eg, they depend on a + // template parameter). + // + // It's kind of a shame not generating them even when they + // could be referenced, but we already do the same for items + // with invalid template parameters, and at least this way + // they can be replaced, instead of generating plain invalid + // code. + let inner_canon_type = + inner_item.expect_type().canonical_type(ctx); + if inner_canon_type.is_invalid_type_param() { + warn!( + "Item contained invalid named type, skipping: \ + {item:?}, {inner_item:?}" + ); + return; + } + } + + 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) + } else { + quote! {} + }; + + 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 + if matches!(inner_rust_type, syn::Type::Path(_)) && + outer_params.is_empty() && + !is_opaque && + alias_style == AliasVariation::TypeAlias && + inner_item.expect_type().canonical_type(ctx).is_enum() + { + tokens.append_all(quote! { + pub use + }); + let path = top_level_path(ctx, item); + tokens.append_separated(path, quote!(::)); + tokens.append_all(quote! { + :: #inner_rust_type as #rust_name ; + }); + result.push(tokens); + return; + } + + tokens.append_all(match alias_style { + AliasVariation::TypeAlias => quote! { + pub type #rust_name + }, + AliasVariation::NewType | AliasVariation::NewTypeDeref => { + let mut attributes = + vec![attributes::repr("transparent")]; + let packed = false; // Types can't be packed in Rust. + let derivable_traits = + derives_of_item(item, ctx, packed); + let mut derives: Vec<_> = derivable_traits.into(); + // 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| { + cb.add_derives(&DeriveInfo { + name: &name, + kind: DeriveTypeKind::Struct, + }) + }); + // In most cases this will be a no-op, since custom_derives will be empty. + append_custom_derives(&mut derives, &custom_derives); + attributes.push(attributes::derives(&derives)); + + let custom_attributes = + ctx.options().all_callbacks(|cb| { + cb.add_attributes(&AttributeInfo { + name: &name, + kind: DeriveTypeKind::Struct, + }) + }); + attributes.extend( + custom_attributes + .iter() + .map(|s| s.parse().unwrap()), + ); + + quote! { + #( #attributes )* + pub struct #rust_name + } + } + }); + + let params: Vec<_> = outer_params + .into_iter() + .filter_map(|p| p.as_template_param(ctx, &())) + .collect(); + if params + .iter() + .any(|p| ctx.resolve_type(*p).is_invalid_type_param()) + { + warn!( + "Item contained invalid template \ + parameter: {item:?}" + ); + return; + } + let params: Vec<_> = params + .iter() + .map(|p| { + p.try_to_rust_ty(ctx, &()).expect( + "type parameters can always convert to rust ty OK", + ) + }) + .collect(); + + if !params.is_empty() { + tokens.append_all(quote! { + < #( #params ),* > + }); + } + + 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) ; + } + } + }); + + if alias_style == AliasVariation::NewTypeDeref { + let prefix = ctx.trait_prefix(); + tokens.append_all(quote! { + impl ::#prefix::ops::Deref for #rust_name { + type Target = #inner_rust_type; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl ::#prefix::ops::DerefMut for #rust_name { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + }); + } + + result.push(tokens); + } + TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item), + TypeKind::ObjCId | TypeKind::ObjCSel => { + result.saw_objc(); + } + TypeKind::ObjCInterface(ref interface) => { + interface.codegen(ctx, result, item); + } + ref u @ TypeKind::UnresolvedTypeRef(..) => { + unreachable!("Should have been resolved after parsing {u:?}!") + } + } + } +} + +struct Vtable<'a> { + item_id: ItemId, + /// A reference to the originating compound object. + #[allow(dead_code)] + comp_info: &'a CompInfo, +} + +impl<'a> Vtable<'a> { + fn new(item_id: ItemId, comp_info: &'a CompInfo) -> Self { + Vtable { item_id, comp_info } + } +} + +impl CodeGenerator for Vtable<'_> { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + assert_eq!(item.id(), self.item_id); + debug_assert!(item.is_enabled_for_codegen(ctx)); + let name = ctx.rust_ident(self.canonical_name(ctx)); + + // For now, we will only generate vtables for classes that: + // - do not inherit from others (compilers merge VTable from primary parent class). + // - do not contain a virtual destructor (requires ordering; platforms generate different vtables). + if ctx.options().vtable_generation && + self.comp_info.base_members().is_empty() && + self.comp_info.destructor().is_none() + { + let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx)); + + let methods = self + .comp_info + .methods() + .iter() + .filter_map(|m| { + if !m.is_virtual() { + return None; + } + + let function_item = ctx.resolve_item(m.signature()); + let function = function_item.expect_function(); + let signature_item = ctx.resolve_item(function.signature()); + 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); + + // FIXME: Need to account for overloading with times_seen (separately from regular function path). + let function_name = ctx.rust_ident(function_name); + let mut args = utils::fnsig_arguments(ctx, signature); + let ret = utils::fnsig_return_ty(ctx, signature); + + args[0] = if m.is_const() { + quote! { this: *const #class_ident } + } else { + quote! { this: *mut #class_ident } + }; + + Some(quote! { + pub #function_name : unsafe extern "C" fn( #( #args ),* ) #ret + }) + }) + .collect::>(); + + result.push(quote! { + #[repr(C)] + 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); + + result.push(quote! { + #[repr(C)] + pub struct #name ( #void ); + }); + } + } +} + +impl ItemCanonicalName for Vtable<'_> { + fn canonical_name(&self, ctx: &BindgenContext) -> String { + format!("{}__bindgen_vtable", self.item_id.canonical_name(ctx)) + } +} + +impl TryToRustTy for Vtable<'_> { + type Extra = (); + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + _: &(), + ) -> error::Result { + let name = ctx.rust_ident(self.canonical_name(ctx)); + Ok(syn::parse_quote! { #name }) + } +} + +impl CodeGenerator for TemplateInstantiation { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + debug_assert!(item.is_enabled_for_codegen(ctx)); + + // Although uses of instantiations don't need code generation, and are + // just converted to rust types in fields, vars, etc, we take this + // opportunity to generate tests for their layout here. If the + // instantiation is opaque, then its presumably because we don't + // properly understand it (maybe because of specializations), and so we + // shouldn't emit layout tests either. + if !ctx.options().layout_tests || self.is_opaque(ctx, item) { + return; + } + + // For consistency with other layout tests, gate this on offset_of. + let compile_time = ctx.options().rust_features().offset_of; + + // If there are any unbound type parameters, then we can't generate a + // layout test because we aren't dealing with a concrete type with a + // concrete size and alignment. + if ctx.uses_any_template_parameters(item.id()) { + return; + } + + let layout = item.kind().expect_type().layout(ctx); + + if let Some(layout) = layout { + let size = layout.size; + let align = layout.align; + + let name = item.full_disambiguated_name(ctx); + let fn_name = if compile_time { + None + } else { + let mut fn_name = + format!("__bindgen_test_layout_{name}_instantiation"); + let times_seen = result.overload_number(&fn_name); + if times_seen > 0 { + write!(&mut fn_name, "_{times_seen}").unwrap(); + } + Some(ctx.rust_ident_raw(fn_name)) + }; + + let prefix = ctx.trait_prefix(); + let ident = item.to_rust_ty_or_opaque(ctx, &()); + let size_of_expr = quote! { + ::#prefix::mem::size_of::<#ident>() + }; + let align_of_expr = quote! { + ::#prefix::mem::align_of::<#ident>() + }; + let size_of_err = + format!("Size of template specialization: {name}"); + let align_of_err = + format!("Align of template specialization: {name}"); + + if compile_time { + // In an ideal world this would be assert_eq!, but that is not + // supported in const fn due to the need for string formatting. + // If #size_of_expr > #size, this will index OOB, and if + // #size_of_expr < #size, the subtraction will overflow, both + // of which print enough information to see what has gone wrong. + result.push(quote! { + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [#size_of_err][#size_of_expr - #size]; + [#align_of_err][#align_of_expr - #align]; + }; + }); + } else { + result.push(quote! { + #[test] + fn #fn_name() { + assert_eq!(#size_of_expr, #size, #size_of_err); + assert_eq!(#align_of_expr, #align, #align_of_err); + } + }); + } + } + } +} + +/// Trait for implementing the code generation of a struct or union field. +trait FieldCodegen<'a> { + type Extra; + + #[allow(clippy::too_many_arguments)] + fn codegen( + &self, + ctx: &BindgenContext, + visibility_kind: FieldVisibilityKind, + accessor_kind: FieldAccessorKind, + parent: &CompInfo, + parent_item: &Item, + last_field: bool, + result: &mut CodegenResult, + struct_layout: &mut StructLayoutTracker, + fields: &mut F, + methods: &mut M, + extra: Self::Extra, + ) where + F: Extend, + M: Extend; +} + +impl FieldCodegen<'_> for Field { + type Extra = (); + + fn codegen( + &self, + ctx: &BindgenContext, + visibility_kind: FieldVisibilityKind, + accessor_kind: FieldAccessorKind, + parent: &CompInfo, + parent_item: &Item, + last_field: bool, + result: &mut CodegenResult, + struct_layout: &mut StructLayoutTracker, + fields: &mut F, + methods: &mut M, + _: (), + ) where + F: Extend, + M: Extend, + { + match *self { + Field::DataMember(ref data) => { + data.codegen( + ctx, + visibility_kind, + accessor_kind, + parent, + parent_item, + last_field, + result, + struct_layout, + fields, + methods, + (), + ); + } + Field::Bitfields(ref unit) => { + unit.codegen( + ctx, + visibility_kind, + accessor_kind, + parent, + parent_item, + last_field, + result, + struct_layout, + fields, + methods, + (), + ); + } + } + } +} + +fn wrap_union_field_if_needed( + ctx: &BindgenContext, + struct_layout: &StructLayoutTracker, + ty: syn::Type, + result: &mut CodegenResult, +) -> syn::Type { + if struct_layout.is_rust_union() { + if struct_layout.can_copy_union_fields() { + ty + } else { + let prefix = ctx.trait_prefix(); + syn::parse_quote! { ::#prefix::mem::ManuallyDrop<#ty> } + } + } else { + result.saw_bindgen_union(); + if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::__BindgenUnionField<#ty> } + } else { + syn::parse_quote! { __BindgenUnionField<#ty> } + } + } +} + +impl FieldCodegen<'_> for FieldData { + type Extra = (); + + fn codegen( + &self, + ctx: &BindgenContext, + parent_visibility_kind: FieldVisibilityKind, + accessor_kind: FieldAccessorKind, + parent: &CompInfo, + parent_item: &Item, + last_field: bool, + result: &mut CodegenResult, + struct_layout: &mut StructLayoutTracker, + fields: &mut F, + methods: &mut M, + _: (), + ) where + F: Extend, + M: Extend, + { + // Bitfields are handled by `FieldCodegen` implementations for + // `BitfieldUnit` and `Bitfield`. + assert!(self.bitfield_width().is_none()); + + let field_item = + self.ty().into_resolver().through_type_refs().resolve(ctx); + let field_ty = field_item.expect_type(); + let ty = self + .ty() + .to_rust_ty_or_opaque(ctx, &()) + .with_implicit_template_params(ctx, field_item); + + // NB: If supported, we use proper `union` types. + let ty = if parent.is_union() { + wrap_union_field_if_needed(ctx, struct_layout, ty, result) + } else if let Some(item) = field_ty.is_incomplete_array(ctx) { + // Only FAM if its the last field + if ctx.options().flexarray_dst && last_field { + struct_layout.saw_flexible_array(); + syn::parse_quote! { FAM } + } else { + result.saw_incomplete_array(); + + let inner = item.to_rust_ty_or_opaque(ctx, &()); + + if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::__IncompleteArrayField<#inner> } + } else { + syn::parse_quote! { __IncompleteArrayField<#inner> } + } + } + } else { + ty + }; + + let mut field = quote! {}; + if ctx.options().generate_comments { + if let Some(raw_comment) = self.comment() { + let comment = ctx.options().process_comment(raw_comment); + field = attributes::doc(&comment); + } + } + + let field_name = self + .name() + .map(|name| ctx.rust_mangle(name).into_owned()) + .expect("Each field should have a name in codegen!"); + let field_name = field_name.as_str(); + let field_ident = ctx.rust_ident_raw(field_name); + + if let Some(padding_field) = + struct_layout.saw_field(field_name, field_ty, self.offset()) + { + fields.extend(Some(padding_field)); + } + + let visibility = compute_visibility( + ctx, + self.is_public(), + ctx.options().last_callback(|cb| { + cb.field_visibility(FieldInfo { + type_name: &parent_item.canonical_name(ctx), + field_name, + field_type_name: field_ty.name(), + }) + }), + self.annotations(), + parent_visibility_kind, + ); + let accessor_kind = + self.annotations().accessor_kind().unwrap_or(accessor_kind); + + match visibility { + FieldVisibilityKind::Private => { + field.append_all(quote! { + #field_ident : #ty , + }); + } + FieldVisibilityKind::PublicCrate => { + field.append_all(quote! { + pub(crate) #field_ident : #ty , + }); + } + FieldVisibilityKind::Public => { + field.append_all(quote! { + pub #field_ident : #ty , + }); + } + } + + fields.extend(Some(field)); + + // TODO: Factor the following code out, please! + if accessor_kind == FieldAccessorKind::None { + return; + } + + let getter_name = ctx.rust_ident_raw(format!("get_{field_name}")); + let mutable_getter_name = + ctx.rust_ident_raw(format!("get_{field_name}_mut")); + + methods.extend(Some(match accessor_kind { + FieldAccessorKind::None => unreachable!(), + FieldAccessorKind::Regular => { + quote! { + #[inline] + pub fn #getter_name(&self) -> & #ty { + &self.#field_ident + } + + #[inline] + pub fn #mutable_getter_name(&mut self) -> &mut #ty { + &mut self.#field_ident + } + } + } + FieldAccessorKind::Unsafe => { + quote! { + #[inline] + pub unsafe fn #getter_name(&self) -> & #ty { + &self.#field_ident + } + + #[inline] + pub unsafe fn #mutable_getter_name(&mut self) -> &mut #ty { + &mut self.#field_ident + } + } + } + FieldAccessorKind::Immutable => { + quote! { + #[inline] + pub fn #getter_name(&self) -> & #ty { + &self.#field_ident + } + } + } + })); + } +} + +impl BitfieldUnit { + /// Get the constructor name for this bitfield unit. + fn ctor_name(&self) -> proc_macro2::TokenStream { + let ctor_name = Ident::new( + &format!("new_bitfield_{}", self.nth()), + Span::call_site(), + ); + quote! { + #ctor_name + } + } +} + +impl Bitfield { + /// Extend an under construction bitfield unit constructor with this + /// bitfield. This sets the relevant bits on the `__bindgen_bitfield_unit` + /// variable that's being constructed. + fn extend_ctor_impl( + &self, + ctx: &BindgenContext, + 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(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; + let prefix = ctx.trait_prefix(); + + ctor_impl.append_all(quote! { + __bindgen_bitfield_unit.set( + #offset, + #width, + { + let #param_name: #bitfield_int_ty = unsafe { + ::#prefix::mem::transmute(#param_name) + }; + #param_name as u64 + } + ); + }); + + ctor_impl + } +} + +fn access_specifier( + visibility: FieldVisibilityKind, +) -> proc_macro2::TokenStream { + match visibility { + FieldVisibilityKind::Private => quote! {}, + FieldVisibilityKind::PublicCrate => quote! { pub(crate) }, + FieldVisibilityKind::Public => quote! { pub }, + } +} + +/// Compute a fields or structs visibility based on multiple conditions. +/// 1. If the element was declared public, and we respect such CXX accesses specs +/// (context option) => By default Public, but this can be overruled by an `annotation`. +/// +/// 2. If the element was declared private, and we respect such CXX accesses specs +/// (context option) => By default Private, but this can be overruled by an `annotation`. +/// +/// 3. If we do not respect visibility modifiers, the result depends on the `annotation`, +/// if any, or the passed `default_kind`. +/// +fn compute_visibility( + ctx: &BindgenContext, + is_declared_public: bool, + callback_override: Option, + annotations: &Annotations, + default_kind: FieldVisibilityKind, +) -> FieldVisibilityKind { + callback_override + .or_else(|| annotations.visibility_kind()) + .unwrap_or_else(|| { + match (is_declared_public, ctx.options().respect_cxx_access_specs) { + (true, true) => { + // declared as public, cxx specs are respected + FieldVisibilityKind::Public + } + (false, true) => { + // declared as private, cxx specs are respected + FieldVisibilityKind::Private + } + (_, false) => { + // cxx specs are not respected, declaration does not matter. + default_kind + } + } + }) +} + +impl FieldCodegen<'_> for BitfieldUnit { + type Extra = (); + + fn codegen( + &self, + ctx: &BindgenContext, + visibility_kind: FieldVisibilityKind, + accessor_kind: FieldAccessorKind, + parent: &CompInfo, + parent_item: &Item, + last_field: bool, + result: &mut CodegenResult, + struct_layout: &mut StructLayoutTracker, + fields: &mut F, + methods: &mut M, + _: (), + ) where + F: Extend, + M: Extend, + { + use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; + + result.saw_bitfield_unit(); + + let layout = self.layout(); + let unit_field_ty = helpers::bitfield_unit(ctx, layout); + let field_ty = { + let unit_field_ty = unit_field_ty.clone(); + if parent.is_union() { + wrap_union_field_if_needed( + ctx, + struct_layout, + unit_field_ty, + result, + ) + } else { + unit_field_ty + } + }; + + let unit_field_name = format!("_bitfield_{}", self.nth()); + let unit_field_ident = ctx.rust_ident(&unit_field_name); + + let ctor_name = self.ctor_name(); + let mut ctor_params = vec![]; + let mut ctor_impl = quote! {}; + + // We cannot generate any constructor if the underlying storage can't + // implement AsRef<[u8]> / AsMut<[u8]> / etc, or can't derive Default. + // + // We don't check `larger_arrays` here because Default does still have + // the 32 items limitation. + let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT; + + let mut unit_visibility = visibility_kind; + let bfields = self.bitfields(); + for (idx, bf) in bfields.iter().enumerate() { + // Codegen not allowed for anonymous bitfields + if bf.name().is_none() { + continue; + } + + let mut bitfield_representable_as_int = true; + let mut bitfield_visibility = visibility_kind; + bf.codegen( + ctx, + visibility_kind, + accessor_kind, + parent, + parent_item, + last_field && idx == bfields.len() - 1, + result, + struct_layout, + fields, + methods, + ( + &unit_field_name, + &unit_field_ty, + &mut bitfield_representable_as_int, + &mut bitfield_visibility, + ), + ); + if bitfield_visibility < unit_visibility { + unit_visibility = bitfield_visibility; + } + + // Generating a constructor requires the bitfield to be representable as an integer. + if !bitfield_representable_as_int { + generate_ctor = false; + continue; + } + + let param_name = bitfield_getter_name(ctx, bf); + let bitfield_ty_item = ctx.resolve_item(bf.ty()); + let bitfield_ty = bitfield_ty_item.expect_type(); + let bitfield_ty = + bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); + + ctor_params.push(quote! { + #param_name : #bitfield_ty + }); + ctor_impl = bf.extend_ctor_impl(ctx, ¶m_name, ctor_impl); + } + + let access_spec = access_specifier(unit_visibility); + + let field = quote! { + #access_spec #unit_field_ident : #field_ty , + }; + fields.extend(Some(field)); + + if generate_ctor { + methods.extend(Some(quote! { + #[inline] + #access_spec fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty { + let mut __bindgen_bitfield_unit: #unit_field_ty = Default::default(); + #ctor_impl + __bindgen_bitfield_unit + } + })); + } + + struct_layout.saw_bitfield_unit(layout); + } +} + +fn bitfield_getter_name( + ctx: &BindgenContext, + bitfield: &Bitfield, +) -> proc_macro2::TokenStream { + let name = bitfield.getter_name(); + let name = ctx.rust_ident_raw(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, +) -> proc_macro2::TokenStream { + let setter = bitfield.setter_name(); + let setter = ctx.rust_ident_raw(setter); + 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 syn::Type, + &'a mut bool, + &'a mut FieldVisibilityKind, + ); + + fn codegen( + &self, + ctx: &BindgenContext, + visibility_kind: FieldVisibilityKind, + _accessor_kind: FieldAccessorKind, + parent: &CompInfo, + parent_item: &Item, + _last_field: bool, + _result: &mut CodegenResult, + struct_layout: &mut StructLayoutTracker, + _fields: &mut F, + methods: &mut M, + ( + unit_field_name, + unit_field_ty, + bitfield_representable_as_int, + bitfield_visibility, + ): ( + &'a str, + &'a syn::Type, + &mut bool, + &'a mut FieldVisibilityKind, + ), + ) where + F: Extend, + M: Extend, + { + 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 = + 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 = + bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); + + let offset = self.offset_into_unit(); + let width = self.width() as u8; + + let override_visibility = self.name().and_then(|field_name| { + ctx.options().last_callback(|cb| { + cb.field_visibility(FieldInfo { + type_name: &parent_item.canonical_name(ctx), + field_name, + field_type_name: bitfield_ty_ident, + }) + }) + }); + *bitfield_visibility = compute_visibility( + ctx, + self.is_public(), + override_visibility, + self.annotations(), + visibility_kind, + ); + let access_spec = access_specifier(*bitfield_visibility); + + if parent.is_union() && !struct_layout.is_rust_union() { + methods.extend(Some(quote! { + #[inline] + #access_spec fn #getter_name(&self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute( + self.#unit_field_ident.as_ref().get(#offset, #width) + as #bitfield_int_ty + ) + } + } + + #[inline] + #access_spec fn #setter_name(&mut self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + self.#unit_field_ident.as_mut().set( + #offset, + #width, + val as u64 + ) + } + } + })); + + 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] + #access_spec fn #getter_name(&self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute( + self.#unit_field_ident.get(#offset, #width) + as #bitfield_int_ty + ) + } + } + + #[inline] + #access_spec fn #setter_name(&mut self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + self.#unit_field_ident.set( + #offset, + #width, + val as u64 + ) + } + } + })); + + 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, + ) + } + } + })); + } + } +} + +impl CodeGenerator for CompInfo { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + 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 + // also don't output template specializations, neither total or partial. + if self.has_non_type_template_params() { + return; + } + + let ty = item.expect_type(); + let layout = ty.layout(ctx); + let mut packed = self.is_packed(ctx, layout.as_ref()); + + let canonical_name = item.canonical_name(ctx); + let canonical_ident = ctx.rust_ident(&canonical_name); + + // Generate the vtable from the method list if appropriate. + // + // TODO: I don't know how this could play with virtual methods that are + // not in the list of methods found by us, we'll see. Also, could the + // order of the vtable pointers vary? + // + // FIXME: Once we generate proper vtables, we need to codegen the + // vtable, but *not* generate a field for it in the case that + // HasVtable::has_vtable_ptr is false but HasVtable::has_vtable is true. + // + // Also, we need to generate the vtable in such a way it "inherits" from + // the parent too. + let is_opaque = item.is_opaque(ctx, &()); + let mut fields = vec![]; + let visibility = item + .annotations() + .visibility_kind() + .unwrap_or(ctx.options().default_visibility); + let mut struct_layout = StructLayoutTracker::new( + ctx, + self, + ty, + &canonical_name, + visibility, + packed, + ); + + let mut generic_param_names = vec![]; + + for (idx, ty) in item.used_template_params(ctx).iter().enumerate() { + let param = ctx.resolve_type(*ty); + let name = param.name().unwrap(); + let ident = ctx.rust_ident(name); + generic_param_names.push(ident.clone()); + + let prefix = ctx.trait_prefix(); + let field_name = ctx.rust_ident(format!("_phantom_{idx}")); + fields.push(quote! { + pub #field_name : ::#prefix::marker::PhantomData< + ::#prefix::cell::UnsafeCell<#ident> + > , + }); + } + + if !is_opaque { + if item.has_vtable_ptr(ctx) { + let vtable = Vtable::new(item.id(), self); + vtable.codegen(ctx, result, item); + + let vtable_type = vtable + .try_to_rust_ty(ctx, &()) + .expect("vtable to Rust type conversion is infallible") + .to_ptr(true); + + fields.push(quote! { + pub vtable_: #vtable_type , + }); + + struct_layout.saw_vtable(); + } + + for base in self.base_members() { + if !base.requires_storage(ctx) { + continue; + } + + let inner_item = ctx.resolve_item(base.ty); + let inner = inner_item + .to_rust_ty_or_opaque(ctx, &()) + .with_implicit_template_params(ctx, inner_item); + let field_name = ctx.rust_ident(&base.field_name); + + struct_layout.saw_base(inner_item.expect_type()); + + let visibility = match ( + base.is_public(), + ctx.options().respect_cxx_access_specs, + ) { + (true, true) => FieldVisibilityKind::Public, + (false, true) => FieldVisibilityKind::Private, + _ => ctx.options().default_visibility, + }; + + let access_spec = access_specifier(visibility); + fields.push(quote! { + #access_spec #field_name: #inner, + }); + } + } + + let mut methods = vec![]; + if !is_opaque { + let struct_accessor_kind = item + .annotations() + .accessor_kind() + .unwrap_or(FieldAccessorKind::None); + let field_decls = self.fields(); + for (idx, field) in field_decls.iter().enumerate() { + field.codegen( + ctx, + visibility, + struct_accessor_kind, + self, + item, + idx == field_decls.len() - 1, + result, + &mut struct_layout, + &mut fields, + &mut methods, + (), + ); + } + // Check whether an explicit padding field is needed + // at the end. + if let Some(comp_layout) = layout { + fields.extend( + struct_layout + .add_tail_padding(&canonical_name, comp_layout), + ); + } + } + + if is_opaque { + // Opaque item should not have generated methods, fields. + debug_assert!(fields.is_empty()); + debug_assert!(methods.is_empty()); + } + + let is_union = self.kind() == CompKind::Union; + let layout = item.kind().expect_type().layout(ctx); + let zero_sized = item.is_zero_sized(ctx); + let forward_decl = self.is_forward_declaration(); + + let mut explicit_align = None; + + // C++ requires every struct to be addressable, so what C++ compilers do + // is making the struct 1-byte sized. + // + // This is apparently not the case for C, see: + // https://github.com/rust-lang/rust-bindgen/issues/551 + // + // Just get the layout, and assume C++ if not. + // + // NOTE: This check is conveniently here to avoid the dummy fields we + // may add for unused template parameters. + if !forward_decl && zero_sized { + let has_address = if is_opaque { + // Generate the address field if it's an opaque type and + // couldn't determine the layout of the blob. + layout.is_none() + } else { + layout.map_or(true, |l| l.size != 0) + }; + + if has_address { + let layout = Layout::new(1, 1); + struct_layout.saw_field_with_layout( + "_address", + layout, + /* offset = */ Some(0), + ); + fields.push(quote! { + pub _address: u8, + }); + } + } + + if is_opaque { + match layout { + Some(l) => { + explicit_align = Some(l.align); + let ty = helpers::blob(ctx, l, false); + fields.push(quote! { + pub _bindgen_opaque_blob: #ty , + }); + } + None => { + if !forward_decl { + warn!("Opaque type without layout! Expect dragons!"); + } + } + } + } else if !is_union && !zero_sized { + if let Some(padding_field) = + layout.and_then(|layout| struct_layout.pad_struct(layout)) + { + fields.push(padding_field); + } + + if let Some(layout) = layout { + if struct_layout.requires_explicit_align(layout) { + if layout.align == 1 { + packed = true; + } else { + explicit_align = Some(layout.align); + } + } + } + } else if is_union && !forward_decl { + 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, + }); + } + } + } + + if forward_decl { + fields.push(quote! { + _unused: [u8; 0], + }); + } + + let (flex_array_generic, flex_inner_ty) = if ctx.options().flexarray_dst + { + match self.flex_array_member(ctx) { + Some(ty) => { + let inner = ty.to_rust_ty_or_opaque(ctx, &()); + ( + Some(quote! { FAM: ?Sized = [ #inner; 0 ] }), + Some(quote! { #inner }), + ) + } + None => (None, None), + } + } else { + (None, None) + }; + + // Generics, including the flexible array member. + // + // generics - generic parameters for the struct declaration + // impl_generics_labels - generic parameters for `impl<...>` + // impl_generics_params - generic parameters for `impl structname<...>` + // + // `impl` blocks are for non-FAM related impls like Default, etc + let (generics, impl_generics_labels, impl_generics_params) = + if !generic_param_names.is_empty() || flex_array_generic.is_some() { + let (flex_sized, flex_fam) = match flex_inner_ty.as_ref() { + None => (None, None), + Some(ty) => ( + Some(quote! { [ #ty; 0 ] }), + Some(quote! { FAM: ?Sized = [ #ty; 0 ] }), + ), + }; + + ( + quote! { + < #( #generic_param_names , )* #flex_fam > + }, + quote! { + < #( #generic_param_names , )* > + }, + quote! { + < #( #generic_param_names , )* #flex_sized > + }, + ) + } else { + (quote! {}, quote! {}, quote! {}) + }; + + let mut attributes = vec![]; + let mut needs_clone_impl = false; + let mut needs_default_impl = false; + let mut needs_debug_impl = false; + 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)); + } + + // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the + // "packed" attr is redundant, and do not include it if so. + if packed && + !is_opaque && + !(explicit_align.is_some() && + self.already_packed(ctx).unwrap_or(false)) + { + let n = layout.map_or(1, |l| l.align); + let packed_repr = if n == 1 { + "packed".to_string() + } else { + format!("packed({n})") + }; + attributes.push(attributes::repr_list(&["C", &packed_repr])); + } else { + attributes.push(attributes::repr("C")); + } + + // 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))] + }); + } + } + + let derivable_traits = derives_of_item(item, ctx, packed); + if !derivable_traits.contains(DerivableTraits::DEBUG) { + needs_debug_impl = ctx.options().derive_debug && + ctx.options().impl_debug && + !ctx.no_debug_by_name(item) && + !item.annotations().disallow_debug(); + } + + if !derivable_traits.contains(DerivableTraits::DEFAULT) { + needs_default_impl = ctx.options().derive_default && + !self.is_forward_declaration() && + !ctx.no_default_by_name(item) && + !item.annotations().disallow_default(); + } + + let all_template_params = item.all_template_params(ctx); + + if derivable_traits.contains(DerivableTraits::COPY) && + !derivable_traits.contains(DerivableTraits::CLONE) + { + needs_clone_impl = true; + } + + if !derivable_traits.contains(DerivableTraits::PARTIAL_EQ) { + needs_partialeq_impl = ctx.options().derive_partialeq && + ctx.options().impl_partialeq && + ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == + CanDerive::Manually; + } + + let mut derives: Vec<_> = derivable_traits.into(); + derives.extend(item.annotations().derives().iter().map(String::as_str)); + + 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| { + cb.add_derives(&DeriveInfo { + name: &canonical_name, + kind: if is_rust_union { + DeriveTypeKind::Union + } else { + DeriveTypeKind::Struct + }, + }) + }); + // In most cases this will be a no-op, since custom_derives will be empty. + append_custom_derives(&mut derives, &custom_derives); + + if !derives.is_empty() { + attributes.push(attributes::derives(&derives)); + } + + attributes.extend( + item.annotations() + .attributes() + .iter() + .map(|s| s.parse().unwrap()), + ); + + let custom_attributes = ctx.options().all_callbacks(|cb| { + cb.add_attributes(&AttributeInfo { + name: &canonical_name, + kind: if is_rust_union { + DeriveTypeKind::Union + } else { + DeriveTypeKind::Struct + }, + }) + }); + attributes.extend(custom_attributes.iter().map(|s| s.parse().unwrap())); + + if item.must_use(ctx) { + attributes.push(attributes::must_use()); + } + + let mut tokens = if is_rust_union { + quote! { + #( #attributes )* + pub union #canonical_ident + } + } else { + quote! { + #( #attributes )* + pub struct #canonical_ident + } + }; + + tokens.append_all(quote! { + #generics { + #( #fields )* + } + }); + result.push(tokens); + + // Generate the inner types and all that stuff. + // + // TODO: In the future we might want to be smart, and use nested + // modules, and whatnot. + for ty in self.inner_types() { + let child_item = ctx.resolve_item(*ty); + // assert_eq!(child_item.parent_id(), item.id()); + child_item.codegen(ctx, result, &()); + } + + // NOTE: Some unexposed attributes (like alignment attributes) may + // 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 {canonical_ident} has an unknown attribute that may affect layout"); + } + + if all_template_params.is_empty() { + if !is_opaque { + for var in self.inner_vars() { + ctx.resolve_item(*var).codegen(ctx, result, &()); + } + } + + if ctx.options().layout_tests && !self.is_forward_declaration() { + if let Some(layout) = layout { + let compile_time = ctx.options().rust_features().offset_of; + let fn_name = if compile_time { + None + } else { + let fn_name = + format!("bindgen_test_layout_{canonical_ident}"); + Some(ctx.rust_ident_raw(fn_name)) + }; + let prefix = ctx.trait_prefix(); + let size_of_expr = quote! { + ::#prefix::mem::size_of::<#canonical_ident>() + }; + let align_of_expr = quote! { + ::#prefix::mem::align_of::<#canonical_ident>() + }; + let size = layout.size; + let align = layout.align; + let size_of_err = format!("Size of {canonical_ident}"); + let align_of_err = + format!("Alignment of {canonical_ident}"); + + let check_struct_align = if compile_time { + quote! { + [#align_of_err][#align_of_expr - #align]; + } + } else { + quote! { + assert_eq!(#align_of_expr, #align, #align_of_err); + } + }; + + let should_skip_field_offset_checks = is_opaque; + + let check_field_offset = if should_skip_field_offset_checks + { + vec![] + } else { + self.fields() + .iter() + .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); + let offset_of_err = format!("Offset of field: {canonical_ident}::{field_name}"); + if compile_time { + quote! { + [#offset_of_err][ + ::#prefix::mem::offset_of!(#canonical_ident, #field_name) - #field_offset + ]; + } + } else { + quote! { + assert_eq!( + unsafe { + ::#prefix::ptr::addr_of!((*ptr).#field_name) as usize - ptr as usize + }, + #field_offset, + #offset_of_err + ); + } + } + }) + }) + .collect() + }; + + let uninit_decl = if check_field_offset.is_empty() || + compile_time + { + None + } else { + // FIXME: When MSRV >= 1.59.0, we can use + // > const PTR: *const #canonical_ident = ::#prefix::mem::MaybeUninit::uninit().as_ptr(); + Some(quote! { + // Use a shared MaybeUninit so that rustc with + // opt-level=0 doesn't take too much stack space, + // see #2218. + const UNINIT: ::#prefix::mem::MaybeUninit<#canonical_ident> = ::#prefix::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + }) + }; + + if compile_time { + result.push(quote! { + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + [#size_of_err][#size_of_expr - #size]; + #check_struct_align + #( #check_field_offset )* + }; + }); + } else { + result.push(quote! { + #[test] + fn #fn_name() { + #uninit_decl + assert_eq!(#size_of_expr, #size, #size_of_err); + #check_struct_align + #( #check_field_offset )* + } + }); + } + } + } + + 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_ne!(method.kind(), MethodKind::Constructor); + method.codegen_method( + ctx, + &mut methods, + &mut method_names, + result, + self, + discovered_id, + ); + } + } + + if ctx.options().codegen_config.constructors() { + for sig in self.constructors() { + Method::new( + MethodKind::Constructor, + *sig, + /* const */ + false, + ) + .codegen_method( + ctx, + &mut methods, + &mut method_names, + result, + self, + discovered_id, + ); + } + } + + if ctx.options().codegen_config.destructors() { + if let Some((kind, destructor)) = self.destructor() { + debug_assert!(kind.is_destructor()); + Method::new(kind, destructor, false).codegen_method( + ctx, + &mut methods, + &mut method_names, + result, + self, + discovered_id, + ); + } + } + } + + // NB: We can't use to_rust_ty here since for opaque types this tries to + // use the specialization knowledge to generate a blob field. + let ty_for_impl = quote! { + #canonical_ident #impl_generics_params + }; + + if needs_clone_impl { + result.push(quote! { + impl #impl_generics_labels Clone for #ty_for_impl { + fn clone(&self) -> Self { *self } + } + }); + } + + if needs_flexarray_impl { + result.push(self.generate_flexarray( + ctx, + &canonical_ident, + flex_inner_ty.as_ref(), + &generic_param_names, + &impl_generics_labels, + )); + } + + if needs_default_impl { + let prefix = ctx.trait_prefix(); + 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 + // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to + // non-zero padding bytes, especially when forwards/backwards compatibility is + // involved. + result.push(quote! { + impl #impl_generics_labels Default for #ty_for_impl { + fn default() -> Self { + #body + } + } + }); + } + + if needs_debug_impl { + let impl_ = impl_debug::gen_debug_impl( + ctx, + self.fields(), + item, + self.kind(), + ); + + let prefix = ctx.trait_prefix(); + + result.push(quote! { + impl #impl_generics_labels ::#prefix::fmt::Debug for #ty_for_impl { + #impl_ + } + }); + } + + if needs_partialeq_impl { + if let Some(impl_) = impl_partialeq::gen_partialeq_impl( + ctx, + self, + item, + &ty_for_impl, + ) { + 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 ),* } + }; + + let prefix = ctx.trait_prefix(); + result.push(quote! { + impl #impl_generics_labels ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds { + #impl_ + } + }); + } + } + + if !methods.is_empty() { + result.push(quote! { + impl #impl_generics_labels #ty_for_impl { + #( #methods )* + } + }); + } + } +} + +impl CompInfo { + fn generate_flexarray( + &self, + ctx: &BindgenContext, + canonical_ident: &Ident, + flex_inner_ty: Option<&proc_macro2::TokenStream>, + generic_param_names: &[Ident], + impl_generics_labels: &proc_macro2::TokenStream, + ) -> proc_macro2::TokenStream { + let prefix = ctx.trait_prefix(); + + let flex_array = flex_inner_ty.as_ref().map(|ty| quote! { [ #ty ] }); + + let dst_ty_for_impl = quote! { + #canonical_ident < #( #generic_param_names , )* #flex_array > + + }; + let sized_ty_for_impl = quote! { + #canonical_ident < #( #generic_param_names , )* [ #flex_inner_ty; 0 ] > + }; + + let layout = if ctx.options().rust_features().layout_for_ptr { + quote! { + pub fn layout(len: usize) -> ::#prefix::alloc::Layout { + // SAFETY: Null pointers are OK if we don't deref them + unsafe { + let p: *const Self = ::#prefix::ptr::from_raw_parts(::#prefix::ptr::null::<()>(), len); + ::#prefix::alloc::Layout::for_value_raw(p) + } + } + } + } else { + quote!() + }; + + let (from_ptr_dst, from_ptr_sized) = if ctx + .options() + .rust_features() + .ptr_metadata + { + let flex_ref_inner = ctx.wrap_unsafe_ops(quote! { + Self::flex_ptr(self, len) + }); + let flex_ref_mut_inner = ctx.wrap_unsafe_ops(quote! { + Self::flex_ptr_mut(self, len).assume_init() + }); + let flex_ptr_inner = ctx.wrap_unsafe_ops(quote! { + &*::#prefix::ptr::from_raw_parts(ptr as *const (), len) + }); + let flex_ptr_mut_inner = ctx.wrap_unsafe_ops(quote! { + // Initialize reference without ever exposing it, as its possibly uninitialized + let mut uninit = ::#prefix::mem::MaybeUninit::<&mut #dst_ty_for_impl>::uninit(); + (uninit.as_mut_ptr() as *mut *mut #dst_ty_for_impl) + .write(::#prefix::ptr::from_raw_parts_mut(ptr as *mut (), len)); + + uninit + }); + + ( + quote! { + #[inline] + pub fn fixed(&self) -> (& #sized_ty_for_impl, usize) { + unsafe { + let (ptr, len) = (self as *const Self).to_raw_parts(); + (&*(ptr as *const #sized_ty_for_impl), len) + } + } + + #[inline] + pub fn fixed_mut(&mut self) -> (&mut #sized_ty_for_impl, usize) { + unsafe { + let (ptr, len) = (self as *mut Self).to_raw_parts(); + (&mut *(ptr as *mut #sized_ty_for_impl), len) + } + } + }, + quote! { + /// Convert a sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + pub unsafe fn flex_ref(&self, len: usize) -> &#dst_ty_for_impl { + // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`. + #flex_ref_inner + } + + /// Convert a mutable sized prefix to an unsized structure with the given length. + /// + /// SAFETY: Underlying storage is initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ref_mut(&mut self, len: usize) -> &mut #dst_ty_for_impl { + // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`. + #flex_ref_mut_inner + } + + /// Construct DST variant from a pointer and a size. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements. + #[inline] + pub unsafe fn flex_ptr<'unbounded>(ptr: *const Self, len: usize) -> &'unbounded #dst_ty_for_impl { + #flex_ptr_inner + } + + /// Construct mutable DST variant from a pointer and a + /// size. The returned `&mut` reference is initialized + /// pointing to memory referenced by `ptr`, but there's + /// no requirement that that memory be initialized. + /// + /// NOTE: lifetime of returned reference is not tied to any underlying storage. + /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements. + #[inline] + pub unsafe fn flex_ptr_mut<'unbounded>( + ptr: *mut Self, + len: usize, + ) -> ::#prefix::mem::MaybeUninit<&'unbounded mut #dst_ty_for_impl> { + #flex_ptr_mut_inner + } + }, + ) + } else { + (quote!(), quote!()) + }; + + quote! { + impl #impl_generics_labels #dst_ty_for_impl { + #layout + #from_ptr_dst + } + + impl #impl_generics_labels #sized_ty_for_impl { + #from_ptr_sized + } + } + } +} + +impl Method { + fn codegen_method( + &self, + ctx: &BindgenContext, + methods: &mut Vec, + 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 | + MethodKind::VirtualDestructor { .. } => cc.destructors(), + MethodKind::Static | + MethodKind::Normal | + MethodKind::Virtual { .. } => cc.methods(), + } + }); + + // TODO(emilio): We could generate final stuff at least. + if self.is_virtual() { + return; // FIXME + } + + // First of all, output the actual function. + let function_item = ctx.resolve_item(self.signature()); + if !function_item.process_before_codegen(ctx, result) { + return; + } + let function = function_item.expect_function(); + let times_seen = function.codegen(ctx, result, function_item); + 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(), + MethodKind::Destructor => "destruct".into(), + _ => function.name().to_owned(), + }; + + 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(); + if !supported_abi { + return; + } + + // Do not generate variadic methods, since rust does not allow + // implementing them, and we don't do a good job at it anyway. + if signature.is_variadic() { + return; + } + + if method_names.contains(&name) { + let mut count = 1; + let mut new_name; + + while { + new_name = format!("{name}{count}"); + method_names.contains(&new_name) + } { + count += 1; + } + + name = new_name; + } + + 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(); + } + let function_name = ctx.rust_ident(function_name); + let mut args = utils::fnsig_arguments(ctx, signature); + let mut ret = utils::fnsig_return_ty(ctx, signature); + + if !self.is_static() && !self.is_constructor() { + args[0] = if self.is_const() { + quote! { &self } + } else { + quote! { &mut self } + }; + } + + // If it's a constructor, we always return `Self`, and we inject the + // "this" parameter, so there's no need to ask the user for it. + // + // Note that constructors in Clang are represented as functions with + // return-type = void. + if self.is_constructor() { + args.remove(0); + ret = quote! { -> Self }; + } + + let mut exprs = + helpers::ast_ty::arguments_from_signature(signature, ctx); + + let mut stmts = vec![]; + + // If it's a constructor, we need to insert an extra parameter with a + // variable called `__bindgen_tmp` we're going to create. + if self.is_constructor() { + let prefix = ctx.trait_prefix(); + 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() { + assert!(!exprs.is_empty()); + exprs[0] = quote! { + self + }; + } + + let call = quote! { + #function_name (#( #exprs ),* ) + }; + + stmts.push(call); + + if self.is_constructor() { + stmts.push(quote! { + __bindgen_tmp.assume_init() + }); + } + + let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*)); + + let mut attrs = vec![attributes::inline()]; + + if signature.must_use() { + attrs.push(attributes::must_use()); + } + + let name = ctx.rust_ident(&name); + methods.push(quote! { + #(#attrs)* + pub unsafe fn #name ( #( #args ),* ) #ret { + #block + } + }); + } +} + +/// A helper type that represents different enum variations. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] +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]`. + Rust { + /// Indicates whether the generated struct should be `#[non_exhaustive]` + non_exhaustive: bool, + }, + /// The code for this enum will use a newtype + NewType { + /// Indicates whether the newtype will have bitwise operators + is_bitfield: bool, + /// Indicates whether the variants will be represented as global constants + is_global: bool, + }, + /// The code for this enum will use consts + #[default] + Consts, + /// The code for this enum will use a module containing consts + ModuleConsts, +} + +impl EnumVariation { + 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) + } +} + +impl fmt::Display for EnumVariation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match self { + Self::Rust { + non_exhaustive: false, + } => "rust", + Self::Rust { + non_exhaustive: true, + } => "rust_non_exhaustive", + Self::NewType { + is_bitfield: true, .. + } => "bitfield", + Self::NewType { + is_bitfield: false, + is_global, + } => { + if *is_global { + "newtype_global" + } else { + "newtype" + } + } + Self::Consts => "consts", + Self::ModuleConsts => "moduleconsts", + }; + s.fmt(f) + } +} + +impl FromStr for EnumVariation { + type Err = std::io::Error; + + /// Create a `EnumVariation` from a string. + fn from_str(s: &str) -> Result { + match s { + "rust" => Ok(EnumVariation::Rust { + non_exhaustive: false, + }), + "rust_non_exhaustive" => Ok(EnumVariation::Rust { + non_exhaustive: true, + }), + "bitfield" => Ok(EnumVariation::NewType { + is_bitfield: true, + is_global: false, + }), + "consts" => Ok(EnumVariation::Consts), + "moduleconsts" => Ok(EnumVariation::ModuleConsts), + "newtype" => Ok(EnumVariation::NewType { + is_bitfield: false, + is_global: false, + }), + "newtype_global" => Ok(EnumVariation::NewType { + is_bitfield: false, + is_global: true, + }), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + concat!( + "Got an invalid EnumVariation. Accepted values ", + "are 'rust', 'rust_non_exhaustive', 'bitfield', 'consts',", + "'moduleconsts', 'newtype' and 'newtype_global'." + ), + )), + } + } +} + +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 EnumBuilderKind { + Rust { + non_exhaustive: bool, + }, + NewType { + is_bitfield: bool, + is_global: bool, + /// if the enum is named or not. + is_anonymous: bool, + }, + Consts { + needs_typedef: bool, + }, + ModuleConsts { + module_name: Ident, + }, +} + +impl EnumBuilder { + /// Returns true if the builder is for a rustified enum. + fn is_rust_enum(&self) -> bool { + 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: &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(); + + let kind = match enum_variation { + EnumVariation::NewType { + is_bitfield, + is_global, + } => EnumBuilderKind::NewType { + is_bitfield, + is_global, + is_anonymous: enum_is_anonymous, + }, + + EnumVariation::Rust { non_exhaustive } => { + EnumBuilderKind::Rust { non_exhaustive } + } + + EnumVariation::Consts => EnumBuilderKind::Consts { + needs_typedef: !has_typedef, + }, + + EnumVariation::ModuleConsts => { + enum_ty = Ident::new( + CONSTIFIED_ENUM_MODULE_REPR_NAME, + Span::call_site(), + ); + + 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( + mut self, + ctx: &BindgenContext, + variant: &EnumVariant, + variant_doc: proc_macro2::TokenStream, + mangling_prefix: Option<&str>, + 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(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), + }; + + match self.kind { + EnumBuilderKind::Rust { .. } => { + let name = ctx.rust_ident(variant_name); + self.enum_variants.push(EnumVariantInfo { + variant_name: name, + variant_doc, + value: expr, + }); + self + } + + EnumBuilderKind::NewType { is_global, .. } => { + let variant_ident = if is_ty_named && !is_global { + ctx.rust_ident(variant_name) + } else { + ctx.rust_ident(match mangling_prefix { + Some(prefix) => { + Cow::Owned(format!("{prefix}_{variant_name}")) + } + None => variant_name, + }) + }; + self.enum_variants.push(EnumVariantInfo { + variant_name: variant_ident, + variant_doc, + value: quote! { #rust_ty ( #expr )}, + }); + + self + } + + EnumBuilderKind::Consts { .. } => { + let constant_name = match mangling_prefix { + Some(prefix) => { + Cow::Owned(format!("{prefix}_{variant_name}")) + } + None => variant_name, + }; + + let ident = ctx.rust_ident(constant_name); + self.enum_variants.push(EnumVariantInfo { + variant_name: ident, + variant_doc, + value: quote! { #expr }, + }); + + self + } + EnumBuilderKind::ModuleConsts { .. } => { + let name = ctx.rust_ident(variant_name); + 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; + + #[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; + } + } + } + } + + fn build( + self, + ctx: &BindgenContext, + rust_ty: &syn::Type, + ) -> proc_macro2::TokenStream { + 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 #enum_ident { + #( #variants )* + } + } + } + EnumBuilderKind::NewType { + is_bitfield, + is_global, + is_anonymous, + } => { + // 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 )* + } + } else { + quote! { + impl #enum_ident { + #( #variants )* + } + } + }; + + let prefix = ctx.trait_prefix(); + let bitfield_impl_opt = is_bitfield + .then(|| Self::newtype_bitfield_impl(&prefix, rust_ty)); + + 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 + + #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 )* + + #typedef_opt + } + } + EnumBuilderKind::ModuleConsts { module_name, .. } => { + quote! { + // 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 )* + } + } + } + } + } +} + +impl CodeGenerator for Enum { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + debug!("::codegen: item = {item:?}"); + debug_assert!(item.is_enabled_for_codegen(ctx)); + + let name = item.canonical_name(ctx); + let ident = ctx.rust_ident(&name); + let enum_ty = item.expect_type(); + let layout = enum_ty.layout(ctx); + let variation = self.computed_enum_variation(ctx, item); + + let repr_translated; + let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) { + Some(repr) + if !ctx.options().translate_enum_integer_types && + !variation.is_rust() => + { + repr + } + repr => { + // An enum's integer type is translated to a native Rust + // integer type in 3 cases: + // * the enum is Rustified and we need a translated type for + // the repr attribute + // * the representation couldn't be determined from the C source + // * it was explicitly requested as a bindgen option + + 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"), + } + } else { + warn!( + "Guessing type of enum! Forward declarations of enums \ + shouldn't be legal!" + ); + IntKind::Int + }; + + let signed = kind.is_signed(); + let size = layout + .map(|l| l.size) + .or_else(|| kind.known_size()) + .unwrap_or(0); + + let translated = match (signed, size) { + (true, 1) => IntKind::I8, + (false, 1) => IntKind::U8, + (true, 2) => IntKind::I16, + (false, 2) => IntKind::U16, + (true, 4) => IntKind::I32, + (false, 4) => IntKind::U32, + (true, 8) => IntKind::I64, + (false, 8) => IntKind::U64, + _ => { + warn!( + "invalid enum decl: signed: {signed}, size: {size}" + ); + IntKind::I32 + } + }; + + repr_translated = + Type::new(None, None, TypeKind::Int(translated), false); + &repr_translated + } + }; + + let mut attrs = vec![]; + + if let Some(comment) = item.comment(ctx) { + attrs.push(attributes::doc(&comment)); + } + + if item.must_use(ctx) { + attrs.push(attributes::must_use()); + } + + if !variation.is_const() { + let packed = false; // Enums can't be packed in Rust. + let mut derives = derives_of_item(item, ctx, packed); + // For backwards compat, enums always derive + // Clone/Eq/PartialEq/Hash, even if we don't generate those by + // default. + derives.insert( + DerivableTraits::CLONE | + DerivableTraits::HASH | + DerivableTraits::PARTIAL_EQ | + DerivableTraits::EQ, + ); + let mut derives: Vec<_> = derives.into(); + for derive in item.annotations().derives() { + if !derives.contains(&derive.as_str()) { + derives.push(derive); + } + } + + // 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| { + cb.add_derives(&DeriveInfo { + name: &name, + kind: DeriveTypeKind::Enum, + }) + }); + // In most cases this will be a no-op, since custom_derives will be empty. + append_custom_derives(&mut derives, &custom_derives); + + attrs.extend( + item.annotations() + .attributes() + .iter() + .map(|s| s.parse().unwrap()), + ); + + // The custom attribute callback may return a list of attributes; + // add them to the end of the list. + let custom_attributes = ctx.options().all_callbacks(|cb| { + cb.add_attributes(&AttributeInfo { + name: &name, + kind: DeriveTypeKind::Enum, + }) + }); + attrs.extend(custom_attributes.iter().map(|s| s.parse().unwrap())); + + attrs.push(attributes::derives(&derives)); + } + + fn add_constant( + ctx: &BindgenContext, + enum_: &Type, + // Only to avoid recomputing every time. + enum_canonical_name: &Ident, + // May be the same as "variant" if it's because the + // enum is unnamed and we still haven't seen the + // value. + variant_name: &Ident, + referenced_name: &Ident, + 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}") + } else { + format!("{variant_name}") + } + } else { + format!("{variant_name}") + }; + let constant_name = ctx.rust_ident(constant_name); + + result.push(quote! { + pub const #constant_name : #enum_rust_ty = + #enum_canonical_name :: #referenced_name ; + }); + } + + let repr = repr.to_rust_ty_or_opaque(ctx, item); + let has_typedef = ctx.is_enum_typedef_combo(item.id()); + + 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(); + let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &()); + let is_toplevel = item.is_toplevel(ctx); + + // Used to mangle the constants we generate in the unnamed-enum case. + let parent_canonical_name = if is_toplevel { + None + } else { + Some(item.parent_id().canonical_name(ctx)) + }; + + let constant_mangling_prefix = if ctx.options().prepend_enum_name { + if enum_ty.name().is_none() { + parent_canonical_name.as_deref() + } else { + Some(&*name) + } + } else { + None + }; + + // NB: We defer the creation of constified variants, in case we find + // another variant with the same value (which is the common thing to + // do). + let mut constified_variants = VecDeque::new(); + + let mut iter = self.variants().iter().peekable(); + while let Some(variant) = + iter.next().or_else(|| constified_variants.pop_front()) + { + if variant.hidden() { + continue; + } + + if variant.force_constification() && iter.peek().is_some() { + constified_variants.push_back(variant); + 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(); + + 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() { + let enum_canonical_name = &ident; + let variant_name = + ctx.rust_ident_raw(&*mangled_name); + result.push(quote! { + impl #enum_rust_ty { + pub const #variant_name : #enum_rust_ty = + #enum_canonical_name :: #existing_variant_name ; + } + }); + } else { + add_constant( + ctx, + enum_ty, + &ident, + &Ident::new(&mangled_name, Span::call_site()), + existing_variant_name, + &enum_rust_ty, + result, + ); + } + } else { + builder = builder.with_variant( + ctx, + variant, + variant_doc, + constant_mangling_prefix, + &enum_rust_ty, + enum_ty.name().is_some(), + ); + } + } + Entry::Vacant(entry) => { + builder = builder.with_variant( + ctx, + variant, + variant_doc, + constant_mangling_prefix, + &enum_rust_ty, + enum_ty.name().is_some(), + ); + + let variant_name = ctx.rust_ident(variant.name()); + + // If it's an unnamed enum, or constification is enforced, + // we also generate a constant so it can be properly + // accessed. + if (variation.is_rust() && enum_ty.name().is_none()) || + variant.force_constification() + { + let mangled_name = if is_toplevel { + variant_name.clone() + } else { + let parent_name = + parent_canonical_name.as_ref().unwrap(); + + Ident::new( + &format!("{parent_name}_{variant_name}"), + Span::call_site(), + ) + }; + + add_constant( + ctx, + enum_ty, + &ident, + &mangled_name, + &variant_name, + &enum_rust_ty, + result, + ); + } + + entry.insert(variant_name); + } + } + } + + 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 { + /// Use i32 or i64 + Signed, + /// Use u32 or u64 + #[default] + Unsigned, +} + +impl fmt::Display for MacroTypeVariation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match self { + Self::Signed => "signed", + Self::Unsigned => "unsigned", + }; + s.fmt(f) + } +} + +impl FromStr for MacroTypeVariation { + type Err = std::io::Error; + + /// Create a `MacroTypeVariation` from a string. + fn from_str(s: &str) -> Result { + match s { + "signed" => Ok(MacroTypeVariation::Signed), + "unsigned" => Ok(MacroTypeVariation::Unsigned), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + concat!( + "Got an invalid MacroTypeVariation. Accepted values ", + "are 'signed' and 'unsigned'" + ), + )), + } + } +} + +/// Enum for how aliases should be translated. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] +pub enum AliasVariation { + /// Convert to regular Rust alias + #[default] + TypeAlias, + /// Create a new type by wrapping the old type in a struct and using #[repr(transparent)] + NewType, + /// Same as `NewType` but also impl Deref to be able to use the methods of the wrapped type + NewTypeDeref, +} + +impl fmt::Display for AliasVariation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match self { + Self::TypeAlias => "type_alias", + Self::NewType => "new_type", + Self::NewTypeDeref => "new_type_deref", + }; + + s.fmt(f) + } +} + +impl FromStr for AliasVariation { + type Err = std::io::Error; + + /// Create an `AliasVariation` from a string. + fn from_str(s: &str) -> Result { + match s { + "type_alias" => Ok(AliasVariation::TypeAlias), + "new_type" => Ok(AliasVariation::NewType), + "new_type_deref" => Ok(AliasVariation::NewTypeDeref), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + concat!( + "Got an invalid AliasVariation. Accepted values ", + "are 'type_alias', 'new_type', and 'new_type_deref'" + ), + )), + } + } +} + +/// Enum for how non-`Copy` `union`s should be translated. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum NonCopyUnionStyle { + /// Wrap members in a type generated by `bindgen`. + BindgenWrapper, + /// Wrap members in [`::core::mem::ManuallyDrop`]. + /// + /// Note: `ManuallyDrop` was stabilized in Rust 1.20.0, do not use it if your + /// MSRV is lower. + ManuallyDrop, +} + +impl fmt::Display for NonCopyUnionStyle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match self { + Self::BindgenWrapper => "bindgen_wrapper", + Self::ManuallyDrop => "manually_drop", + }; + + s.fmt(f) + } +} + +impl Default for NonCopyUnionStyle { + fn default() -> Self { + Self::BindgenWrapper + } +} + +impl FromStr for NonCopyUnionStyle { + type Err = std::io::Error; + + fn from_str(s: &str) -> Result { + match s { + "bindgen_wrapper" => Ok(Self::BindgenWrapper), + "manually_drop" => Ok(Self::ManuallyDrop), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + concat!( + "Got an invalid NonCopyUnionStyle. Accepted values ", + "are 'bindgen_wrapper' and 'manually_drop'" + ), + )), + } + } +} + +/// Fallible conversion to an opaque blob. +/// +/// Implementors of this trait should provide the `try_get_layout` method to +/// fallibly get this thing's layout, which the provided `try_to_opaque` trait +/// method will use to convert the `Layout` into an opaque blob Rust type. +pub(crate) trait TryToOpaque { + type Extra; + + /// Get the layout for this thing, if one is available. + fn try_get_layout( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> error::Result; + + /// Do not override this provided trait method. + fn try_to_opaque( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> error::Result { + self.try_get_layout(ctx, extra) + .map(|layout| helpers::blob(ctx, layout, true)) + } +} + +/// Infallible conversion of an IR thing to an opaque blob. +/// +/// The resulting layout is best effort, and is unfortunately not guaranteed to +/// be correct. When all else fails, we fall back to a single byte layout as a +/// last resort, because C++ does not permit zero-sized types. See the note in +/// the `ToRustTyOrOpaque` doc comment about fallible versus infallible traits +/// and when each is appropriate. +/// +/// Don't implement this directly. Instead implement `TryToOpaque`, and then +/// leverage the blanket impl for this trait. +pub(crate) trait ToOpaque: TryToOpaque { + fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout { + self.try_get_layout(ctx, extra) + .unwrap_or_else(|_| Layout::for_size(ctx, 1)) + } + + fn to_opaque( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> syn::Type { + let layout = self.get_layout(ctx, extra); + helpers::blob(ctx, layout, true) + } +} + +impl ToOpaque for T where T: TryToOpaque {} + +/// Fallible conversion from an IR thing to an *equivalent* Rust type. +/// +/// If the C/C++ construct represented by the IR thing cannot (currently) be +/// represented in Rust (for example, instantiations of templates with +/// const-value generic parameters) then the impl should return an `Err`. It +/// should *not* attempt to return an opaque blob with the correct size and +/// alignment. That is the responsibility of the `TryToOpaque` trait. +pub(crate) trait TryToRustTy { + type Extra; + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + extra: &Self::Extra, + ) -> error::Result; +} + +/// Fallible conversion to a Rust type or an opaque blob with the correct size +/// and alignment. +/// +/// Don't implement this directly. Instead implement `TryToRustTy` and +/// `TryToOpaque`, and then leverage the blanket impl for this trait below. +pub(crate) trait TryToRustTyOrOpaque: TryToRustTy + TryToOpaque { + type Extra; + + fn try_to_rust_ty_or_opaque( + &self, + ctx: &BindgenContext, + extra: &::Extra, + ) -> error::Result; +} + +impl TryToRustTyOrOpaque for T +where + T: TryToRustTy + TryToOpaque, +{ + type Extra = E; + + fn try_to_rust_ty_or_opaque( + &self, + ctx: &BindgenContext, + extra: &E, + ) -> 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, true)) + } else { + Err(Error::NoLayoutForOpaqueBlob) + } + }) + } +} + +/// Infallible conversion to a Rust type, or an opaque blob with a best effort +/// of correct size and alignment. +/// +/// Don't implement this directly. Instead implement `TryToRustTy` and +/// `TryToOpaque`, and then leverage the blanket impl for this trait below. +/// +/// ### Fallible vs. Infallible Conversions to Rust Types +/// +/// When should one use this infallible `ToRustTyOrOpaque` trait versus the +/// 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 +/// `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. +pub(crate) trait ToRustTyOrOpaque: TryToRustTy + ToOpaque { + type Extra; + + fn to_rust_ty_or_opaque( + &self, + ctx: &BindgenContext, + extra: &::Extra, + ) -> syn::Type; +} + +impl ToRustTyOrOpaque for T +where + T: TryToRustTy + ToOpaque, +{ + type Extra = E; + + fn to_rust_ty_or_opaque( + &self, + ctx: &BindgenContext, + extra: &E, + ) -> syn::Type { + self.try_to_rust_ty(ctx, extra) + .unwrap_or_else(|_| self.to_opaque(ctx, extra)) + } +} + +impl TryToOpaque for T +where + T: Copy + Into, +{ + type Extra = (); + + fn try_get_layout( + &self, + ctx: &BindgenContext, + _: &(), + ) -> error::Result { + ctx.resolve_item((*self).into()).try_get_layout(ctx, &()) + } +} + +impl TryToRustTy for T +where + T: Copy + Into, +{ + type Extra = (); + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + _: &(), + ) -> error::Result { + ctx.resolve_item((*self).into()).try_to_rust_ty(ctx, &()) + } +} + +impl TryToOpaque for Item { + type Extra = (); + + fn try_get_layout( + &self, + ctx: &BindgenContext, + _: &(), + ) -> error::Result { + self.kind().expect_type().try_get_layout(ctx, self) + } +} + +impl TryToRustTy for Item { + type Extra = (); + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + _: &(), + ) -> error::Result { + self.kind().expect_type().try_to_rust_ty(ctx, self) + } +} + +impl TryToOpaque for Type { + type Extra = Item; + + fn try_get_layout( + &self, + ctx: &BindgenContext, + _: &Item, + ) -> error::Result { + self.layout(ctx).ok_or(Error::NoLayoutForOpaqueBlob) + } +} + +impl TryToRustTy for Type { + type Extra = Item; + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + item: &Item, + ) -> error::Result { + use self::helpers::ast_ty::*; + + match *self.kind() { + TypeKind::Void => Ok(c_void(ctx)), + // TODO: we should do something smart with nullptr, or maybe *const + // c_void is enough? + TypeKind::NullPtr => Ok(c_void(ctx).to_ptr(true)), + TypeKind::Int(ik) => { + Ok(int_kind_rust_type(ctx, ik, self.layout(ctx))) + } + TypeKind::Float(fk) => { + Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))) + } + TypeKind::Complex(fk) => { + let float_path = + float_kind_rust_type(ctx, fk, self.layout(ctx)); + + ctx.generated_bindgen_complex(); + Ok(if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::__BindgenComplex<#float_path> } + } else { + syn::parse_quote! { __BindgenComplex<#float_path> } + }) + } + TypeKind::Function(ref signature) => { + // We can't rely on the sizeof(Option>) == + // sizeof(NonZero<_>) optimization with opaque blobs (because + // they aren't NonZero), so don't *ever* use an or_opaque + // variant here. + let ty = signature.try_to_rust_ty(ctx, item)?; + + let prefix = ctx.trait_prefix(); + Ok(syn::parse_quote! { ::#prefix::option::Option<#ty> }) + } + TypeKind::Array(item, len) | TypeKind::Vector(item, len) => { + let ty = item.try_to_rust_ty(ctx, &())?; + Ok(syn::parse_quote! { [ #ty ; #len ] }) + } + TypeKind::Enum(..) => { + let path = item.namespace_aware_canonical_path(ctx); + let path = proc_macro2::TokenStream::from_str(&path.join("::")) + .unwrap(); + Ok(syn::parse_quote!(#path)) + } + TypeKind::TemplateInstantiation(ref inst) => { + inst.try_to_rust_ty(ctx, item) + } + TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), + TypeKind::TemplateAlias(..) | + TypeKind::Alias(..) | + TypeKind::BlockPointer(..) => { + if self.is_block_pointer() && !ctx.options().generate_block { + let void = c_void(ctx); + return Ok(void.to_ptr(/* is_const = */ false)); + } + + if item.is_opaque(ctx, &()) && + item.used_template_params(ctx) + .into_iter() + .any(|param| param.is_template_param(ctx, &())) + { + self.try_to_opaque(ctx, item) + } else if let Some(ty) = self + .name() + .and_then(|name| utils::type_from_named(ctx, name)) + { + Ok(ty) + } else { + utils::build_path(item, ctx) + } + } + TypeKind::Comp(ref info) => { + let template_params = item.all_template_params(ctx); + if info.has_non_type_template_params() || + (item.is_opaque(ctx, &()) && !template_params.is_empty()) + { + return self.try_to_opaque(ctx, item); + } + + utils::build_path(item, ctx) + } + TypeKind::Opaque => self.try_to_opaque(ctx, item), + TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { + // Check that this type has the same size as the target's pointer type. + let size = self.get_layout(ctx, item).size; + if size != ctx.target_pointer_size() { + return Err(Error::InvalidPointerSize { + ty_name: self.name().unwrap_or("unknown").into(), + ty_size: size, + ptr_size: ctx.target_pointer_size(), + }); + } + + let is_const = ctx.resolve_type(inner).is_const(); + + let inner = + inner.into_resolver().through_type_refs().resolve(ctx); + let inner_ty = inner.expect_type(); + + let is_objc_pointer = + matches!(inner_ty.kind(), TypeKind::ObjCInterface(..)); + + // Regardless if we can properly represent the inner type, we + // should always generate a proper pointer here, so use + // infallible conversion of the inner type. + let ty = inner + .to_rust_ty_or_opaque(ctx, &()) + .with_implicit_template_params(ctx, inner); + + // Avoid the first function pointer level, since it's already + // represented in Rust. + 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)) + } + } + TypeKind::TypeParam => { + let name = item.canonical_name(ctx); + let ident = ctx.rust_ident(name); + Ok(syn::parse_quote! { #ident }) + } + TypeKind::ObjCSel => Ok(syn::parse_quote! { objc::runtime::Sel }), + TypeKind::ObjCId => Ok(syn::parse_quote! { id }), + TypeKind::ObjCInterface(ref interface) => { + let name = ctx.rust_ident(interface.name()); + Ok(syn::parse_quote! { #name }) + } + ref u @ TypeKind::UnresolvedTypeRef(..) => { + unreachable!("Should have been resolved after parsing {u:?}!") + } + } + } +} + +impl TryToOpaque for TemplateInstantiation { + type Extra = Item; + + fn try_get_layout( + &self, + ctx: &BindgenContext, + item: &Item, + ) -> error::Result { + item.expect_type() + .layout(ctx) + .ok_or(Error::NoLayoutForOpaqueBlob) + } +} + +impl TryToRustTy for TemplateInstantiation { + type Extra = Item; + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + item: &Item, + ) -> error::Result { + if self.is_opaque(ctx, item) { + return Err(Error::InstantiationOfOpaqueType); + } + + let def = self + .template_definition() + .into_resolver() + .through_type_refs() + .resolve(ctx); + + let mut ty = quote! {}; + let def_path = def.namespace_aware_canonical_path(ctx); + ty.append_separated( + def_path.into_iter().map(|p| ctx.rust_ident(p)), + quote!(::), + ); + + let def_params = def.self_template_params(ctx); + if def_params.is_empty() { + // This can happen if we generated an opaque type for a partial + // template specialization, and we've hit an instantiation of + // that partial specialization. + extra_assert!(def.is_opaque(ctx, &())); + return Err(Error::InstantiationOfOpaqueType); + } + + // TODO: If the definition type is a template class/struct + // definition's member template definition, it could rely on + // generic template parameters from its outer template + // class/struct. When we emit bindings for it, it could require + // *more* type arguments than we have here, and we will need to + // reconstruct them somehow. We don't have any means of doing + // that reconstruction at this time. + + let template_args = self + .template_arguments() + .iter() + .zip(def_params.iter()) + // Only pass type arguments for the type parameters that + // the def uses. + .filter(|&(_, param)| ctx.uses_template_parameter(def.id(), *param)) + .map(|(arg, _)| { + let arg = arg.into_resolver().through_type_refs().resolve(ctx); + let ty = arg + .try_to_rust_ty(ctx, &())? + .with_implicit_template_params(ctx, arg); + Ok(ty) + }) + .collect::>>()?; + + Ok(if template_args.is_empty() { + syn::parse_quote! { #ty } + } else { + syn::parse_quote! { #ty<#(#template_args),*> } + }) + } +} + +impl TryToRustTy for FunctionSig { + type Extra = Item; + + fn try_to_rust_ty( + &self, + ctx: &BindgenContext, + item: &Item, + ) -> error::Result { + // TODO: we might want to consider ignoring the reference return value. + let ret = utils::fnsig_return_ty(ctx, self); + let arguments = utils::fnsig_arguments(ctx, self); + + match self.abi(ctx, None) { + Ok(abi) => Ok( + syn::parse_quote! { unsafe extern #abi fn ( #( #arguments ),* ) #ret }, + ), + Err(err) => { + if matches!(err, Error::UnsupportedAbi(_)) { + unsupported_abi_diagnostic( + self.name(), + self.is_variadic(), + item.location(), + ctx, + &err, + ); + } + + Err(err) + } + } + } +} + +impl CodeGenerator for Function { + type Extra = Item; + + /// If we've actually generated the symbol, the number of times we've seen + /// it. + type Return = Option; + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) -> Self::Return { + 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 TypeKind::Function(ref signature) = *signature.kind() else { + panic!("Signature kind is not a Function: {signature:?}") + }; + + if is_internal { + if !ctx.options().wrap_static_fns { + // We cannot do anything with internal functions if we are not wrapping them so + // just avoid generating anything for them. + return None; + } + + if signature.is_variadic() { + // We cannot generate wrappers for variadic static functions so we avoid + // generating any code for them. + variadic_fn_diagnostic(self.name(), item.location(), ctx); + 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() + } + FunctionKind::Method(_) => false, + }; + + // Similar to static member variables in a class template, we can't + // generate bindings to template functions, because the set of + // instantiations is open ended and we have no way of knowing which + // monomorphizations actually exist. + if !item.all_template_params(ctx).is_empty() { + return None; + } + + let name = self.name(); + let mut canonical_name = item.canonical_name(ctx); + let mangled_name = self.mangled_name(); + + { + let seen_symbol_name = mangled_name.unwrap_or(&canonical_name); + + // TODO: Maybe warn here if there's a type/argument mismatch, or + // something? + if result.seen_function(seen_symbol_name) { + return None; + } + result.saw_function(seen_symbol_name); + } + + let mut attributes = vec![]; + + if true { + let must_use = signature.must_use() || { + let ret_ty = signature + .return_type() + .into_resolver() + .through_type_refs() + .resolve(ctx); + ret_ty.must_use(ctx) + }; + + if must_use { + attributes.push(attributes::must_use()); + } + } + + if let Some(comment) = item.comment(ctx) { + attributes.push(attributes::doc(&comment)); + } + + let abi = match signature.abi(ctx, Some(name)) { + Err(err) => { + if matches!(err, Error::UnsupportedAbi(_)) { + unsupported_abi_diagnostic( + name, + signature.is_variadic(), + item.location(), + ctx, + &err, + ); + } + + return None; + } + Ok(ClangAbi::Unknown(unknown_abi)) => { + panic!( + "Invalid or unknown abi {unknown_abi:?} for function {canonical_name:?} ({self:?})" + ); + } + Ok(abi) => abi, + }; + + // Handle overloaded functions by giving each overload its own unique + // suffix. + let times_seen = result.overload_number(&canonical_name); + if times_seen > 0 { + write!(&mut canonical_name, "{times_seen}").unwrap(); + } + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Function { + final_name: canonical_name.clone(), + } + }); + + 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)); + } + } + + 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 && + link_name_attr.is_none(); + + if should_wrap { + let name = canonical_name.clone() + ctx.wrap_static_fns_suffix(); + attributes.push(attributes::link_name::(&name)); + } + + let wrap_as_variadic = if should_wrap && !signature.is_variadic() { + utils::wrap_as_variadic_fn(ctx, signature, name) + } else { + None + }; + + let (ident, args) = if let Some(WrapAsVariadic { + idx_of_va_list_arg, + new_name, + }) = &wrap_as_variadic + { + ( + new_name, + utils::fnsig_arguments_iter( + ctx, + // Prune argument at index (idx_of_va_list_arg) + signature.argument_types().iter().enumerate().filter_map( + |(idx, t)| { + if idx == *idx_of_va_list_arg { + None + } else { + Some(t) + } + }, + ), + // and replace it by a `...` (variadic symbol and the end of the signature) + true, + ), + ) + } else { + (&canonical_name, utils::fnsig_arguments(ctx, signature)) + }; + 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! { + #block_attributes + #safety extern #abi { + #(#attributes)* + pub fn #ident ( #( #args ),* ) #ret; + } + }; + + // Add the item to the serialization list if necessary + if should_wrap { + result + .items_to_serialize + .push((item.id(), wrap_as_variadic)); + } + + // 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, + symbol, + abi, + signature.is_variadic(), + ctx.options().dynamic_link_require_all, + &args, + &args_identifiers, + &ret, + &ret_ty, + &attributes, + ctx, + ); + } else { + result.push(tokens); + } + Some(times_seen) + } +} + +#[cfg_attr(not(feature = "experimental"), allow(unused_variables))] +fn unsupported_abi_diagnostic( + fn_name: &str, + variadic: bool, + location: Option<&crate::clang::SourceLocation>, + ctx: &BindgenContext, + error: &Error, +) { + warn!( + "Skipping {}function `{fn_name}` because the {error}", + if variadic { "variadic " } else { "" }, + ); + + #[cfg(feature = "experimental")] + if ctx.options().emit_diagnostics { + use crate::diagnostics::{get_line, Diagnostic, Level, Slice}; + + let mut diag = Diagnostic::default(); + diag.with_title( + format!( + "Skipping {}function `{fn_name}` because the {error}", + if variadic { "variadic " } else { "" }, + ), + Level::Warning, + ) + .add_annotation( + "No code will be generated for this function.", + Level::Warning, + ) + .add_annotation( + format!( + "The configured Rust version is {}.", + ctx.options().rust_target + ), + Level::Note, + ); + + if let Some(loc) = location { + let (file, line, col, _) = loc.location(); + + if let Some(filename) = file.name() { + if let Ok(Some(source)) = get_line(&filename, line) { + let mut slice = Slice::default(); + slice + .with_source(source) + .with_location(filename, line, col); + diag.add_slice(slice); + } + } + } + + diag.display(); + } +} + +fn variadic_fn_diagnostic( + fn_name: &str, + _location: Option<&crate::clang::SourceLocation>, + _ctx: &BindgenContext, +) { + warn!( + "Cannot generate wrapper for the static variadic function `{fn_name}`." + ); + + #[cfg(feature = "experimental")] + if _ctx.options().emit_diagnostics { + use crate::diagnostics::{get_line, Diagnostic, Level, Slice}; + + let mut diag = Diagnostic::default(); + + 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); + + if let Some(loc) = _location { + let (file, line, col, _) = loc.location(); + + if let Some(filename) = file.name() { + if let Ok(Some(source)) = get_line(&filename, line) { + let mut slice = Slice::default(); + slice + .with_source(source) + .with_location(filename, line, col); + diag.add_slice(slice); + } + } + } + + diag.display(); + } +} + +fn objc_method_codegen( + ctx: &BindgenContext, + method: &ObjCMethod, + methods: &mut Vec, + class_name: Option<&str>, + rust_class_name: &str, + prefix: &str, +) { + // 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()); + if ctx.options().blocklisted_items.matches(name) { + return; + } + + let signature = method.signature(); + let fn_args = utils::fnsig_arguments(ctx, signature); + let fn_ret = utils::fnsig_return_ty(ctx, signature); + + let sig = if method.is_class_method() { + quote! { + ( #( #fn_args ),* ) #fn_ret + } + } else { + let self_arr = [quote! { &self }]; + let args = self_arr.iter().chain(fn_args.iter()); + quote! { + ( #( #args ),* ) #fn_ret + } + }; + + let methods_and_args = method.format_method_call(&fn_args); + + let body = { + let body = if method.is_class_method() { + let class_name = ctx.rust_ident( + class_name + .expect("Generating a class method without class name?"), + ); + quote!(msg_send!(class!(#class_name), #methods_and_args)) + } else { + quote!(msg_send!(*self, #methods_and_args)) + }; + + ctx.wrap_unsafe_ops(body) + }; + + let method_name = ctx.rust_ident(format!("{prefix}{}", method.rust_name())); + + methods.push(quote! { + unsafe fn #method_name #sig where ::Target: objc::Message + Sized { + #body + } + }); +} + +impl CodeGenerator for ObjCInterface { + type Extra = Item; + type Return = (); + + fn codegen( + &self, + ctx: &BindgenContext, + result: &mut CodegenResult<'_>, + item: &Item, + ) { + debug_assert!(item.is_enabled_for_codegen(ctx)); + + let mut impl_items = vec![]; + let rust_class_name = item.path_for_allowlisting(ctx)[1..].join("::"); + + for method in self.methods() { + objc_method_codegen( + ctx, + method, + &mut impl_items, + None, + &rust_class_name, + "", + ); + } + + for class_method in self.class_methods() { + let ambiquity = self + .methods() + .iter() + .map(|m| m.rust_name()) + .any(|x| x == class_method.rust_name()); + let prefix = if ambiquity { "class_" } else { "" }; + objc_method_codegen( + ctx, + class_method, + &mut impl_items, + Some(self.name()), + &rust_class_name, + prefix, + ); + } + + let trait_name = ctx.rust_ident(self.rust_name()); + let trait_constraints = quote! { + Sized + std::ops::Deref + }; + let trait_block = if self.is_template() { + let template_names: Vec = self + .template_names + .iter() + .map(|g| ctx.rust_ident(g)) + .collect(); + + quote! { + pub trait #trait_name <#(#template_names:'static),*> : #trait_constraints { + #( #impl_items )* + } + } + } else { + quote! { + pub trait #trait_name : #trait_constraints { + #( #impl_items )* + } + } + }; + + let class_name = ctx.rust_ident(self.name()); + if !self.is_category() && !self.is_protocol() { + let struct_block = quote! { + #[repr(transparent)] + #[derive(Debug, Copy, Clone)] + pub struct #class_name(pub id); + impl std::ops::Deref for #class_name { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { + &*self.0 + } + } + } + unsafe impl objc::Message for #class_name { } + impl #class_name { + pub fn alloc() -> Self { + Self(unsafe { + msg_send!(class!(#class_name), alloc) + }) + } + } + }; + result.push(struct_block); + let mut protocol_set: HashSet = Default::default(); + 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)) + .name() + .unwrap(), + ); + let impl_trait = quote! { + impl #protocol_name for #class_name { } + }; + result.push(impl_trait); + } + let mut parent_class = self.parent_class; + while let Some(parent_id) = parent_class { + let parent = parent_id + .expect_type_id(ctx) + .into_resolver() + .through_type_refs() + .resolve(ctx) + .expect_type() + .kind(); + + let TypeKind::ObjCInterface(parent) = parent else { + break; + }; + parent_class = parent.parent_class; + + let parent_name = ctx.rust_ident(parent.rust_name()); + let impl_trait = if parent.is_template() { + let template_names: Vec = parent + .template_names + .iter() + .map(|g| ctx.rust_ident(g)) + .collect(); + quote! { + impl <#(#template_names :'static),*> #parent_name <#(#template_names),*> for #class_name { + } + } + } else { + quote! { + impl #parent_name for #class_name { } + } + }; + result.push(impl_trait); + 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)) + .name() + .unwrap(), + ); + let impl_trait = quote! { + impl #protocol_name for #class_name { } + }; + result.push(impl_trait); + } + } + if !parent.is_template() { + let parent_struct_name = parent.name(); + let child_struct_name = self.name(); + let parent_struct = ctx.rust_ident(parent_struct_name); + let from_block = quote! { + impl From<#class_name> for #parent_struct { + fn from(child: #class_name) -> #parent_struct { + #parent_struct(child.0) + } + } + }; + result.push(from_block); + + let error_msg = format!( + "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 { + type Error = &'static str; + fn try_from(parent: #parent_struct) -> Result<#class_name, Self::Error> { + let is_kind_of : bool = unsafe { msg_send!(parent, isKindOfClass:class!(#class_name))}; + if is_kind_of { + Ok(#class_name(parent.0)) + } else { + Err(#error_msg) + } + } + } + }; + result.push(try_into_block); + } + } + } + + if !self.is_protocol() { + let impl_block = if self.is_template() { + let template_names: Vec = self + .template_names + .iter() + .map(|g| ctx.rust_ident(g)) + .collect(); + quote! { + impl <#(#template_names :'static),*> #trait_name <#(#template_names),*> for #class_name { + } + } + } else { + quote! { + impl #trait_name for #class_name { + } + } + }; + result.push(impl_block); + } + + result.push(trait_block); + result.saw_objc(); + } +} + +pub(crate) fn codegen( + context: BindgenContext, +) -> Result<(proc_macro2::TokenStream, BindgenOptions), CodegenError> { + context.gen(|context| { + let _t = context.timer("codegen"); + let counter = Cell::new(0); + let mut result = CodegenResult::new(&counter); + + debug!("codegen: {:?}", context.options()); + + if context.options().emit_ir { + let codegen_items = context.codegen_items(); + for (id, item) in context.items() { + if codegen_items.contains(&id) { + println!("ir: {id:?} = {item:#?}"); + } + } + } + + 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}" + ), + Err(e) => warn!("{e}"), + } + } + + if let Some(spec) = context.options().depfile.as_ref() { + match spec.write(context.deps()) { + Ok(()) => info!( + "Your depfile was generated successfully into: {}", + spec.depfile_path.display() + ), + Err(e) => warn!("{e}"), + } + } + + context.resolve_item(context.root_module()).codegen( + context, + &mut result, + &(), + ); + + 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.push(dynamic_items_tokens); + } + + utils::serialize_items(&result, context)?; + + Ok(postprocessing::postprocessing( + result.items, + context.options(), + )) + }) +} + +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}; + use crate::ir::item::{Item, ItemCanonicalPath}; + use crate::ir::ty::TypeKind; + use crate::{args_are_cpp, file_is_cpp}; + use std::borrow::Cow; + use std::io::Write; + use std::mem; + use std::path::PathBuf; + use std::str::FromStr; + + pub(super) fn serialize_items( + result: &CodegenResult, + context: &BindgenContext, + ) -> Result<(), CodegenError> { + if result.items_to_serialize.is_empty() { + return Ok(()); + } + + 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(); + + if !dir.exists() { + std::fs::create_dir_all(dir)?; + } + + let is_cpp = args_are_cpp(&context.options().clang_args) || + context + .options() + .input_headers + .iter() + .any(|h| file_is_cpp(h)); + + let source_path = path.with_extension(if is_cpp { "cpp" } else { "c" }); + + let mut code = Vec::new(); + + if !context.options().input_headers.is_empty() { + for header in &context.options().input_headers { + writeln!(code, "#include \"{header}\"")?; + } + + writeln!(code)?; + } + + if !context.options().input_header_contents.is_empty() { + for (name, contents) in &context.options().input_header_contents { + writeln!(code, "// {name}\n{contents}")?; + } + + writeln!(code)?; + } + + writeln!(code, "// Static wrappers\n")?; + + for (id, wrap_as_variadic) in &result.items_to_serialize { + let item = context.resolve_item(*id); + item.serialize(context, wrap_as_variadic, &mut vec![], &mut code)?; + } + + std::fs::write(source_path, code)?; + + Ok(()) + } + + pub(super) fn wrap_as_variadic_fn( + ctx: &BindgenContext, + signature: &FunctionSig, + name: &str, + ) -> Option { + // Fast path, exclude because: + // - with 0 args: no va_list possible, so no point searching for one + // - with 1 args: cannot have a `va_list` and another arg (required by va_start) + if signature.argument_types().len() <= 1 { + return None; + } + + let mut it = signature.argument_types().iter().enumerate().filter_map( + |(idx, (_name, mut type_id))| { + // Hand rolled visitor that checks for the presence of `va_list` + loop { + let ty = ctx.resolve_type(type_id); + if Some("__builtin_va_list") == ty.name() { + return Some(idx); + } + match ty.kind() { + TypeKind::Alias(type_id_alias) => { + type_id = *type_id_alias; + } + TypeKind::ResolvedTypeRef(type_id_typedef) => { + type_id = *type_id_typedef; + } + _ => break, + } + } + None + }, + ); + + // Return THE idx (by checking that there is no idx after) + // This is done since we cannot handle multiple `va_list` + it.next().filter(|_| it.next().is_none()).and_then(|idx| { + // Call the `wrap_as_variadic_fn` callback + #[cfg(feature = "experimental")] + { + ctx.options() + .last_callback(|c| c.wrap_as_variadic_fn(name)) + .map(|new_name| super::WrapAsVariadic { + new_name, + idx_of_va_list_arg: idx, + }) + } + #[cfg(not(feature = "experimental"))] + { + let _ = name; + let _ = idx; + None + } + }) + } + + pub(crate) fn prepend_bitfield_unit_type( + ctx: &BindgenContext, + result: &mut Vec, + ) { + if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) || + ctx.options().blocklisted_types.matches(BITFIELD_UNIT) + { + return; + } + + let bitfield_unit_src = include_str!("./bitfield_unit.rs"); + let bitfield_unit_src = if true { + Cow::Borrowed(bitfield_unit_src) + } else { + Cow::Owned(bitfield_unit_src.replace("const fn ", "fn ")) + }; + let bitfield_unit_type = + proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap(); + let bitfield_unit_type = quote!(#bitfield_unit_type); + + let items = vec![bitfield_unit_type]; + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_objc_header( + ctx: &BindgenContext, + result: &mut Vec, + ) { + let use_objc = if ctx.options().objc_extern_crate { + quote! { + #[macro_use] + extern crate objc; + } + } else { + quote! { + use objc::{self, msg_send, sel, sel_impl, class}; + } + }; + + let id_type = quote! { + #[allow(non_camel_case_types)] + pub type id = *mut objc::runtime::Object; + }; + + let items = vec![use_objc, id_type]; + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_block_header( + ctx: &BindgenContext, + result: &mut Vec, + ) { + let use_block = if ctx.options().block_extern_crate { + quote! { + extern crate block; + } + } else { + quote! { + use block; + } + }; + + let items = vec![use_block]; + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_union_types( + ctx: &BindgenContext, + result: &mut Vec, + ) { + let prefix = ctx.trait_prefix(); + + // If the target supports `const fn`, declare eligible functions + // as `const fn` else just `fn`. + let const_fn = if true { + quote! { const fn } + } else { + quote! { fn } + }; + + // TODO(emilio): The fmt::Debug impl could be way nicer with + // std::intrinsics::type_name, but... + let union_field_decl = quote! { + #[repr(C)] + pub struct __BindgenUnionField(::#prefix::marker::PhantomData); + }; + + let transmute = + ctx.wrap_unsafe_ops(quote!(::#prefix::mem::transmute(self))); + + let union_field_impl = quote! { + impl __BindgenUnionField { + #[inline] + pub #const_fn new() -> Self { + __BindgenUnionField(::#prefix::marker::PhantomData) + } + + #[inline] + pub unsafe fn as_ref(&self) -> &T { + #transmute + } + + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { + #transmute + } + } + }; + + let union_field_default_impl = quote! { + impl ::#prefix::default::Default for __BindgenUnionField { + #[inline] + fn default() -> Self { + Self::new() + } + } + }; + + let union_field_clone_impl = quote! { + impl ::#prefix::clone::Clone for __BindgenUnionField { + #[inline] + fn clone(&self) -> Self { + *self + } + } + }; + + let union_field_copy_impl = quote! { + impl ::#prefix::marker::Copy for __BindgenUnionField {} + }; + + let union_field_debug_impl = quote! { + impl ::#prefix::fmt::Debug for __BindgenUnionField { + fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>) + -> ::#prefix::fmt::Result { + fmt.write_str("__BindgenUnionField") + } + } + }; + + // The actual memory of the filed will be hashed, so that's why these + // field doesn't do anything with the hash. + let union_field_hash_impl = quote! { + impl ::#prefix::hash::Hash for __BindgenUnionField { + fn hash(&self, _state: &mut H) { + } + } + }; + + let union_field_partialeq_impl = quote! { + impl ::#prefix::cmp::PartialEq for __BindgenUnionField { + fn eq(&self, _other: &__BindgenUnionField) -> bool { + true + } + } + }; + + let union_field_eq_impl = quote! { + impl ::#prefix::cmp::Eq for __BindgenUnionField { + } + }; + + let items = vec![ + union_field_decl, + union_field_impl, + union_field_default_impl, + union_field_clone_impl, + union_field_copy_impl, + union_field_debug_impl, + union_field_hash_impl, + union_field_partialeq_impl, + union_field_eq_impl, + ]; + + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_incomplete_array_types( + ctx: &BindgenContext, + result: &mut Vec, + ) { + let prefix = ctx.trait_prefix(); + + // If the target supports `const fn`, declare eligible functions + // as `const fn` else just `fn`. + let const_fn = if true { + quote! { const fn } + } else { + quote! { fn } + }; + + let incomplete_array_decl = quote! { + #[repr(C)] + #[derive(Default)] + pub struct __IncompleteArrayField( + ::#prefix::marker::PhantomData, [T; 0]); + }; + + let from_raw_parts = ctx.wrap_unsafe_ops(quote! ( + ::#prefix::slice::from_raw_parts(self.as_ptr(), len) + )); + let from_raw_parts_mut = ctx.wrap_unsafe_ops(quote! ( + ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + )); + + let incomplete_array_impl = quote! { + impl __IncompleteArrayField { + #[inline] + pub #const_fn new() -> Self { + __IncompleteArrayField(::#prefix::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] { + #from_raw_parts + } + + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + #from_raw_parts_mut + } + } + }; + + let incomplete_array_debug_impl = quote! { + impl ::#prefix::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>) + -> ::#prefix::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } + } + }; + + let items = vec![ + incomplete_array_decl, + incomplete_array_impl, + incomplete_array_debug_impl, + ]; + + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_float16_type( + result: &mut Vec, + ) { + let float16_type = quote! { + #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] + #[repr(transparent)] + pub struct __BindgenFloat16(pub u16); + }; + + let items = vec![float16_type]; + let old_items = mem::replace(result, items); + result.extend(old_items); + } + + pub(crate) fn prepend_complex_type( + result: &mut Vec, + ) { + let complex_type = quote! { + #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] + #[repr(C)] + pub struct __BindgenComplex { + pub re: T, + pub im: T + } + }; + + let items = vec![complex_type]; + let old_items = mem::replace(result, items); + 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, + ) -> error::Result { + let path = item.namespace_aware_canonical_path(ctx); + let tokens = + proc_macro2::TokenStream::from_str(&path.join("::")).unwrap(); + + Ok(syn::parse_quote! { #tokens }) + } + + fn primitive_ty(ctx: &BindgenContext, name: &str) -> syn::Type { + let ident = ctx.rust_ident_raw(name); + syn::parse_quote! { #ident } + } + + pub(crate) fn type_from_named( + ctx: &BindgenContext, + name: &str, + ) -> Option { + // FIXME: We could use the inner item to check this is really a + // primitive type but, who the heck overrides these anyway? + Some(match name { + "int8_t" => primitive_ty(ctx, "i8"), + "uint8_t" => primitive_ty(ctx, "u8"), + "int16_t" => primitive_ty(ctx, "i16"), + "uint16_t" => primitive_ty(ctx, "u16"), + "int32_t" => primitive_ty(ctx, "i32"), + "uint32_t" => primitive_ty(ctx, "u32"), + "int64_t" => primitive_ty(ctx, "i64"), + "uint64_t" => primitive_ty(ctx, "u64"), + + "size_t" if ctx.options().size_t_is_usize => { + primitive_ty(ctx, "usize") + } + "uintptr_t" => primitive_ty(ctx, "usize"), + + "ssize_t" if ctx.options().size_t_is_usize => { + primitive_ty(ctx, "isize") + } + "intptr_t" | "ptrdiff_t" => primitive_ty(ctx, "isize"), + _ => return None, + }) + } + + fn fnsig_return_ty_internal( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> syn::Type { + if sig.is_divergent() { + return syn::parse_quote! { ! }; + } + + let canonical_type_kind = sig + .return_type() + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(ctx) + .kind() + .expect_type() + .kind(); + + match canonical_type_kind { + TypeKind::Void => syn::parse_quote! { () }, + _ => sig.return_type().to_rust_ty_or_opaque(ctx, &()), + } + } + + pub(crate) fn fnsig_return_ty( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> proc_macro2::TokenStream { + match fnsig_return_ty_internal(ctx, sig) { + syn::Type::Tuple(syn::TypeTuple { elems, .. }) + if elems.is_empty() => + { + quote! {} + } + ty => quote! { -> #ty }, + } + } + + pub(crate) fn fnsig_argument_type( + ctx: &BindgenContext, + ty: TypeId, + ) -> syn::Type { + use super::ToPtr; + + let arg_item = ctx.resolve_item(ty); + let arg_ty = arg_item.kind().expect_type(); + + // From the C90 standard[1]: + // + // A declaration of a parameter as "array of type" shall be + // adjusted to "qualified pointer to type", where the type + // qualifiers (if any) are those specified within the [ and ] of + // the array type derivation. + // + // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html + match *arg_ty.canonical_type(ctx).kind() { + TypeKind::Array(t, _) => { + let stream = if ctx.options().array_pointers_in_arguments { + arg_ty.to_rust_ty_or_opaque(ctx, arg_item) + } else { + t.to_rust_ty_or_opaque(ctx, &()) + }; + stream + .to_ptr(ctx.resolve_type(t).is_const() || arg_ty.is_const()) + } + TypeKind::Pointer(inner) => { + let inner = ctx.resolve_item(inner); + let inner_ty = inner.expect_type(); + if let TypeKind::ObjCInterface(ref interface) = + *inner_ty.canonical_type(ctx).kind() + { + let name = ctx.rust_ident(interface.name()); + syn::parse_quote! { #name } + } else { + arg_item.to_rust_ty_or_opaque(ctx, &()) + } + } + _ => arg_item.to_rust_ty_or_opaque(ctx, &()), + } + } + + pub(crate) fn fnsig_arguments_iter< + 'a, + I: Iterator, TypeId)>, + >( + ctx: &BindgenContext, + args_iter: I, + is_variadic: bool, + ) -> Vec { + let mut unnamed_arguments = 0; + let mut args = args_iter + .map(|(name, ty)| { + let arg_ty = fnsig_argument_type(ctx, *ty); + + 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()); + let arg_name = ctx.rust_ident(arg_name); + + quote! { + #arg_name : #arg_ty + } + }) + .collect::>(); + + if is_variadic { + args.push(quote! { ... }); + } + + args + } + + pub(crate) fn fnsig_arguments( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> Vec { + fnsig_arguments_iter( + ctx, + sig.argument_types().iter(), + sig.is_variadic(), + ) + } + + pub(crate) fn fnsig_argument_identifiers( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> Vec { + let mut unnamed_arguments = 0; + let args = sig + .argument_types() + .iter() + .map(|&(ref name, _ty)| { + 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()); + let arg_name = ctx.rust_ident(arg_name); + + quote! { + #arg_name + } + }) + .collect::>(); + + args + } + + pub(crate) fn fnsig_block( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> proc_macro2::TokenStream { + let args = sig.argument_types().iter().map(|&(_, ty)| { + let arg_item = ctx.resolve_item(ty); + + arg_item.to_rust_ty_or_opaque(ctx, &()) + }); + + let ret_ty = fnsig_return_ty_internal(ctx, sig); + quote! { + *const ::block::Block<(#(#args,)*), #ret_ty> + } + } + + // Returns true if `canonical_name` will end up as `mangled_name` at the + // machine code level, i.e. after LLVM has applied any target specific + // mangling. + pub(crate) fn names_will_be_identical_after_mangling( + canonical_name: &str, + mangled_name: &str, + call_conv: Option, + ) -> bool { + // If the mangled name and the canonical name are the same then no + // mangling can have happened between the two versions. + if canonical_name == mangled_name { + return true; + } + + // Working with &[u8] makes indexing simpler than with &str + let canonical_name = canonical_name.as_bytes(); + let mangled_name = mangled_name.as_bytes(); + + let (mangling_prefix, expect_suffix) = match call_conv { + Some(ClangAbi::Known(Abi::C | Abi::CUnwind)) | + // None is the case for global variables + None => { + (b'_', false) + } + Some(ClangAbi::Known(Abi::Stdcall)) => (b'_', true), + Some(ClangAbi::Known(Abi::Fastcall)) => (b'@', true), + + // This is something we don't recognize, stay on the safe side + // by emitting the `#[link_name]` attribute + Some(_) => return false, + }; + + // Check that the mangled name is long enough to at least contain the + // canonical name plus the expected prefix. + if mangled_name.len() < canonical_name.len() + 1 { + return false; + } + + // Return if the mangled name does not start with the prefix expected + // for the given calling convention. + if mangled_name[0] != mangling_prefix { + return false; + } + + // Check that the mangled name contains the canonical name after the + // prefix + if &mangled_name[1..=canonical_name.len()] != canonical_name { + return false; + } + + // If the given calling convention also prescribes a suffix, check that + // it exists too + if expect_suffix { + let suffix = &mangled_name[canonical_name.len() + 1..]; + + // The shortest suffix is "@0" + if suffix.len() < 2 { + return false; + } + + // Check that the suffix starts with '@' and is all ASCII decimals + // after that. + if suffix[0] != b'@' || !suffix[1..].iter().all(u8::is_ascii_digit) + { + return false; + } + } else if mangled_name.len() != canonical_name.len() + 1 { + // If we don't expect a prefix but there is one, we need the + // #[link_name] attribute + return false; + } + + 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 new file mode 100644 index 0000000000..e0f6a34baa --- /dev/null +++ b/bindgen/codegen/postprocessing/merge_extern_blocks.rs @@ -0,0 +1,72 @@ +use syn::{ + visit_mut::{visit_file_mut, visit_item_mod_mut, VisitMut}, + File, Item, ItemForeignMod, ItemMod, +}; + +pub(super) fn merge_extern_blocks(file: &mut File) { + Visitor.visit_file_mut(file); +} + +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); + } + + 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); + } +} + +fn visit_items(items: &mut Vec) { + // Keep all the extern blocks in a different `Vec` for faster search. + let mut extern_blocks = Vec::::new(); + + for item in std::mem::take(items) { + if let Item::ForeignMod(ItemForeignMod { + attrs, + abi, + brace_token, + unsafety, + items: extern_block_items, + }) = item + { + let mut exists = false; + for extern_block in &mut extern_blocks { + // Check if there is a extern block with the same ABI and + // attributes. + if extern_block.attrs == attrs && extern_block.abi == abi { + // Merge the items of the two blocks. + extern_block.items.extend_from_slice(&extern_block_items); + exists = true; + break; + } + } + // If no existing extern block had the same ABI and attributes, store + // it. + if !exists { + extern_blocks.push(ItemForeignMod { + attrs, + abi, + brace_token, + unsafety, + items: extern_block_items, + }); + } + } else { + // If the item is not an extern block, we don't have to do anything and just + // push it back. + items.push(item); + } + } + + // Move all the extern blocks alongside the rest of the items. + for extern_block in extern_blocks { + items.push(Item::ForeignMod(extern_block)); + } +} diff --git a/bindgen/codegen/postprocessing/mod.rs b/bindgen/codegen/postprocessing/mod.rs new file mode 100644 index 0000000000..9641698521 --- /dev/null +++ b/bindgen/codegen/postprocessing/mod.rs @@ -0,0 +1,57 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::{parse2, File}; + +use crate::BindgenOptions; + +mod merge_extern_blocks; +mod sort_semantically; + +use merge_extern_blocks::merge_extern_blocks; +use sort_semantically::sort_semantically; + +struct PostProcessingPass { + should_run: fn(&BindgenOptions) -> bool, + run: fn(&mut File), +} + +// TODO: This can be a const fn when mutable references are allowed in const +// context. +macro_rules! pass { + ($pass:ident) => { + PostProcessingPass { + should_run: |options| options.$pass, + run: |file| $pass(file), + } + }; +} + +const PASSES: &[PostProcessingPass] = + &[pass!(merge_extern_blocks), pass!(sort_semantically)]; + +pub(crate) fn postprocessing( + items: Vec, + options: &BindgenOptions, +) -> TokenStream { + let items = items.into_iter().collect(); + let require_syn = PASSES.iter().any(|pass| (pass.should_run)(options)); + + if !require_syn { + return items; + } + + // This syn business is a hack, for now. This means that we are re-parsing already + // generated code using `syn` (as opposed to `quote`) because `syn` provides us more + // control over the elements. + // The `unwrap` here is deliberate because bindgen should generate valid rust items at all + // times. + let mut file = parse2::(items).unwrap(); + + for pass in PASSES { + if (pass.should_run)(options) { + (pass.run)(&mut file); + } + } + + file.into_token_stream() +} diff --git a/bindgen/codegen/postprocessing/sort_semantically.rs b/bindgen/codegen/postprocessing/sort_semantically.rs new file mode 100644 index 0000000000..e9bb5dc308 --- /dev/null +++ b/bindgen/codegen/postprocessing/sort_semantically.rs @@ -0,0 +1,46 @@ +use syn::{ + visit_mut::{visit_file_mut, visit_item_mod_mut, VisitMut}, + File, Item, ItemMod, +}; + +pub(super) fn sort_semantically(file: &mut File) { + Visitor.visit_file_mut(file); +} + +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); + } + + 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); + } +} + +fn visit_items(items: &mut [Item]) { + items.sort_by_key(|item| match item { + Item::Type(_) => 0, + Item::Struct(_) => 1, + Item::Const(_) => 2, + Item::Fn(_) => 3, + Item::Enum(_) => 4, + Item::Union(_) => 5, + Item::Static(_) => 6, + Item::Trait(_) => 7, + Item::TraitAlias(_) => 8, + Item::Impl(_) => 9, + Item::Mod(_) => 10, + Item::Use(_) => 11, + Item::Verbatim(_) => 12, + Item::ExternCrate(_) => 13, + Item::ForeignMod(_) => 14, + Item::Macro(_) => 15, + _ => 18, + }); +} diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs new file mode 100644 index 0000000000..9af48aa8ff --- /dev/null +++ b/bindgen/codegen/serialize.rs @@ -0,0 +1,443 @@ +use std::io::Write; + +use crate::callbacks::IntKind; + +use crate::ir::comp::CompKind; +use crate::ir::context::{BindgenContext, TypeId}; +use crate::ir::function::{Function, FunctionKind}; +use crate::ir::item::Item; +use crate::ir::item::ItemCanonicalName; +use crate::ir::item_kind::ItemKind; +use crate::ir::ty::{FloatKind, Type, TypeKind}; + +use super::{CodegenError, WrapAsVariadic}; + +fn get_loc(item: &Item) -> String { + item.location() + .map_or_else(|| "unknown".to_owned(), |x| x.to_string()) +} + +pub(super) trait CSerialize<'a> { + type Extra; + + fn serialize( + &self, + ctx: &BindgenContext, + extra: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError>; +} + +impl<'a> CSerialize<'a> for Item { + type Extra = &'a Option; + + fn serialize( + &self, + ctx: &BindgenContext, + extra: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + match self.kind() { + ItemKind::Function(func) => { + func.serialize(ctx, (self, extra), stack, writer) + } + kind => Err(CodegenError::Serialize { + msg: format!("Cannot serialize item kind {kind:?}"), + loc: get_loc(self), + }), + } + } +} + +impl<'a> CSerialize<'a> for Function { + type Extra = (&'a Item, &'a Option); + + fn serialize( + &self, + ctx: &BindgenContext, + (item, wrap_as_variadic): Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + if self.kind() != FunctionKind::Function { + return Err(CodegenError::Serialize { + msg: format!( + "Cannot serialize function kind {:?}", + self.kind(), + ), + loc: get_loc(item), + }); + } + + let TypeKind::Function(signature) = + ctx.resolve_type(self.signature()).kind() + else { + unreachable!() + }; + + assert!(!signature.is_variadic()); + + let name = self.name(); + + // Function arguments stored as `(name, type_id)` tuples. + let args = { + let mut count = 0; + + let idx_to_prune = wrap_as_variadic.as_ref().map( + |WrapAsVariadic { + idx_of_va_list_arg, .. + }| *idx_of_va_list_arg, + ); + + signature + .argument_types() + .iter() + .cloned() + .enumerate() + .filter_map(|(idx, (opt_name, type_id))| { + if Some(idx) == idx_to_prune { + None + } else { + Some(( + opt_name.unwrap_or_else(|| { + let name = format!("arg_{count}"); + count += 1; + name + }), + type_id, + )) + } + }) + .collect::>() + }; + + // The name used for the wrapper self. + let wrap_name = format!("{name}{}", ctx.wrap_static_fns_suffix()); + + // The function's return type + let (ret_item, ret_ty) = { + let type_id = signature.return_type(); + let ret_item = ctx.resolve_item(type_id); + let ret_ty = ret_item.expect_type(); + + // Write `ret_ty`. + ret_ty.serialize(ctx, ret_item, stack, writer)?; + + (ret_item, ret_ty) + }; + + const INDENT: &str = " "; + + // Write `wrap_name(args`. + 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}(")?; + } else { + write!(writer, ") {{ return {name}(")?; + } + } else { + // Write `, ...) {` + writeln!(writer, ", ...) {{")?; + + // Declare the return type `RET_TY ret;` if their is a need to do so + if !ret_ty.is_void() { + write!(writer, "{INDENT}")?; + ret_ty.serialize(ctx, ret_item, stack, writer)?; + writeln!(writer, " ret;")?; + } + + // Setup va_list + writeln!(writer, "{INDENT}va_list ap;\n")?; + writeln!( + writer, + "{INDENT}va_start(ap, {});", + args.last().unwrap().0 + )?; + + write!(writer, "{INDENT}")?; + // Write `ret = name(` or `name(` depending if the function returns something + if !ret_ty.is_void() { + write!(writer, "ret = ")?; + } + write!(writer, "{name}(")?; + } + + // Get the arguments names and insert at the right place if necessary `ap` + let mut args: Vec<_> = args.into_iter().map(|(name, _)| name).collect(); + if let Some(WrapAsVariadic { + idx_of_va_list_arg, .. + }) = wrap_as_variadic + { + args.insert(*idx_of_va_list_arg, "ap".to_owned()); + } + + // Write `arg_names);`. + serialize_sep(", ", args.iter(), ctx, writer, |name, _, buf| { + write!(buf, "{name}").map_err(From::from) + })?; + #[rustfmt::skip] + write!(writer, ");{}", if wrap_as_variadic.is_none() { " " } else { "\n" })?; + + if wrap_as_variadic.is_some() { + // End va_list and return the result if their is one + writeln!(writer, "{INDENT}va_end(ap);")?; + if !ret_ty.is_void() { + writeln!(writer, "{INDENT}return ret;")?; + } + } + + writeln!(writer, "}}")?; + + Ok(()) + } +} + +impl CSerialize<'_> for TypeId { + type Extra = (); + + fn serialize( + &self, + ctx: &BindgenContext, + (): Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + let item = ctx.resolve_item(*self); + item.expect_type().serialize(ctx, item, stack, writer) + } +} + +impl<'a> CSerialize<'a> for Type { + type Extra = &'a Item; + + fn serialize( + &self, + ctx: &BindgenContext, + item: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + match self.kind() { + TypeKind::Void => { + if self.is_const() { + write!(writer, "const ")?; + } + write!(writer, "void")?; + } + TypeKind::NullPtr => { + if self.is_const() { + write!(writer, "const ")?; + } + write!(writer, "nullptr_t")?; + } + TypeKind::Int(int_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match int_kind { + IntKind::Bool => write!(writer, "bool")?, + IntKind::SChar => write!(writer, "signed char")?, + IntKind::UChar => write!(writer, "unsigned char")?, + IntKind::WChar => write!(writer, "wchar_t")?, + IntKind::Short => write!(writer, "short")?, + IntKind::UShort => write!(writer, "unsigned short")?, + IntKind::Int => write!(writer, "int")?, + IntKind::UInt => write!(writer, "unsigned int")?, + IntKind::Long => write!(writer, "long")?, + IntKind::ULong => write!(writer, "unsigned long")?, + IntKind::LongLong => write!(writer, "long long")?, + IntKind::ULongLong => write!(writer, "unsigned long long")?, + IntKind::Char { .. } => write!(writer, "char")?, + int_kind => { + return Err(CodegenError::Serialize { + msg: format!( + "Cannot serialize integer kind {int_kind:?}" + ), + loc: get_loc(item), + }) + } + } + } + TypeKind::Float(float_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match float_kind { + FloatKind::Float16 => write!(writer, "_Float16")?, + FloatKind::Float => write!(writer, "float")?, + FloatKind::Double => write!(writer, "double")?, + FloatKind::LongDouble => write!(writer, "long double")?, + FloatKind::Float128 => write!(writer, "__float128")?, + } + } + TypeKind::Complex(float_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match float_kind { + FloatKind::Float16 => write!(writer, "_Float16 complex")?, + FloatKind::Float => write!(writer, "float complex")?, + FloatKind::Double => write!(writer, "double complex")?, + FloatKind::LongDouble => { + write!(writer, "long double complex")?; + } + FloatKind::Float128 => write!(writer, "__complex128")?, + } + } + TypeKind::Alias(type_id) => { + if let Some(name) = self.name() { + if self.is_const() { + write!(writer, "const {name}")?; + } else { + write!(writer, "{name}")?; + } + } else { + type_id.serialize(ctx, (), stack, writer)?; + } + } + TypeKind::Array(type_id, length) => { + type_id.serialize(ctx, (), stack, writer)?; + write!(writer, " [{length}]")?; + } + TypeKind::Function(signature) => { + if self.is_const() { + stack.push("const ".to_string()); + } + + signature.return_type().serialize( + ctx, + (), + &mut vec![], + writer, + )?; + + write!(writer, " (")?; + while let Some(item) = stack.pop() { + write!(writer, "{item}")?; + } + write!(writer, ")")?; + + let args = signature.argument_types(); + if args.is_empty() { + write!(writer, " (void)")?; + } else { + write!(writer, " (")?; + serialize_sep( + ", ", + args.iter(), + ctx, + writer, + |(name, type_id), ctx, buf| { + let mut stack = vec![]; + if let Some(name) = name { + stack.push(name.clone()); + } + type_id.serialize(ctx, (), &mut stack, buf) + }, + )?; + write!(writer, ")")?; + } + } + TypeKind::ResolvedTypeRef(type_id) => { + if self.is_const() { + write!(writer, "const ")?; + } + type_id.serialize(ctx, (), stack, writer)?; + } + TypeKind::Pointer(type_id) => { + if self.is_const() { + stack.push("*const ".to_owned()); + } else { + stack.push("*".to_owned()); + } + type_id.serialize(ctx, (), stack, writer)?; + } + TypeKind::Comp(comp_info) => { + if self.is_const() { + write!(writer, "const ")?; + } + + let name = item.canonical_name(ctx); + + match comp_info.kind() { + CompKind::Struct => write!(writer, "struct {name}")?, + CompKind::Union => write!(writer, "union {name}")?, + } + } + TypeKind::Enum(_enum_ty) => { + if self.is_const() { + write!(writer, "const ")?; + } + + let name = item.canonical_name(ctx); + write!(writer, "enum {name}")?; + } + ty => { + return Err(CodegenError::Serialize { + 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}")?; + } + } + + Ok(()) + } +} + +fn serialize_args( + args: &[(String, TypeId)], + ctx: &BindgenContext, + writer: &mut W, +) -> Result<(), CodegenError> { + if args.is_empty() { + write!(writer, "void")?; + } else { + serialize_sep( + ", ", + args.iter(), + ctx, + writer, + |(name, type_id), ctx, buf| { + type_id.serialize(ctx, (), &mut vec![name.clone()], buf) + }, + )?; + } + + Ok(()) +} + +fn serialize_sep< + W: Write, + F: FnMut(I::Item, &BindgenContext, &mut W) -> Result<(), CodegenError>, + I: Iterator, +>( + sep: &str, + mut iter: I, + ctx: &BindgenContext, + buf: &mut W, + mut f: F, +) -> Result<(), CodegenError> { + if let Some(item) = iter.next() { + f(item, ctx, buf)?; + let sep = sep.as_bytes(); + for item in iter { + buf.write_all(sep)?; + f(item, ctx, buf)?; + } + } + + Ok(()) +} diff --git a/src/codegen/struct_layout.rs b/bindgen/codegen/struct_layout.rs similarity index 79% rename from src/codegen/struct_layout.rs rename to bindgen/codegen/struct_layout.rs index 657be0b489..3dfd076c25 100644 --- a/src/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -6,29 +6,33 @@ use crate::ir::comp::CompInfo; use crate::ir::context::BindgenContext; use crate::ir::layout::Layout; use crate::ir::ty::{Type, TypeKind}; -use proc_macro2::{self, Ident, Span}; +use crate::FieldVisibilityKind; +use proc_macro2::{Ident, Span}; use std::cmp; const MAX_GUARANTEED_ALIGN: usize = 8; /// Trace the layout of struct. #[derive(Debug)] -pub struct StructLayoutTracker<'a> { +pub(crate) struct StructLayoutTracker<'a> { name: &'a str, ctx: &'a BindgenContext, comp: &'a CompInfo, is_packed: bool, known_type_layout: Option, is_rust_union: bool, + can_copy_union_fields: bool, latest_offset: usize, padding_count: usize, latest_field_layout: Option, max_field_align: usize, last_field_was_bitfield: bool, + visibility: FieldVisibilityKind, + last_field_was_flexible_array: bool, } /// Returns a size aligned to a given value. -pub fn align_to(size: usize, align: usize) -> usize { +pub(crate) fn align_to(size: usize, align: usize) -> usize { if align == 0 { return size; } @@ -41,23 +45,6 @@ pub 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 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); @@ -67,51 +54,49 @@ 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 fn new( + pub(crate) fn new( ctx: &'a BindgenContext, comp: &'a CompInfo, ty: &'a Type, name: &'a str, + visibility: FieldVisibilityKind, + is_packed: bool, ) -> Self { let known_type_layout = ty.layout(ctx); - let is_packed = comp.is_packed(ctx, known_type_layout.as_ref()); - let is_rust_union = comp.is_union() && - comp.can_be_rust_union(ctx, known_type_layout.as_ref()); + let (is_rust_union, can_copy_union_fields) = + comp.is_rust_union(ctx, known_type_layout.as_ref(), name); StructLayoutTracker { name, ctx, comp, + visibility, is_packed, known_type_layout, is_rust_union, + can_copy_union_fields, latest_offset: 0, padding_count: 0, latest_field_layout: None, max_field_align: 0, last_field_was_bitfield: false, + last_field_was_flexible_array: false, } } - pub fn is_rust_union(&self) -> bool { + pub(crate) fn can_copy_union_fields(&self) -> bool { + self.can_copy_union_fields + } + + pub(crate) fn is_rust_union(&self) -> bool { self.is_rust_union } - pub fn saw_vtable(&mut self) { + pub(crate) fn saw_flexible_array(&mut self) { + self.last_field_was_flexible_array = true; + } + + pub(crate) fn saw_vtable(&mut self) { debug!("saw vtable for {}", self.name); let ptr_size = self.ctx.target_pointer_size(); @@ -120,7 +105,7 @@ impl<'a> StructLayoutTracker<'a> { self.max_field_align = ptr_size; } - pub fn saw_base(&mut self, base_ty: &Type) { + pub(crate) fn saw_base(&mut self, base_ty: &Type) { debug!("saw base for {}", self.name); if let Some(layout) = base_ty.layout(self.ctx) { self.align_to_latest_field(layout); @@ -131,8 +116,8 @@ impl<'a> StructLayoutTracker<'a> { } } - pub fn saw_bitfield_unit(&mut self, layout: Layout) { - debug!("saw bitfield unit for {}: {:?}", self.name, layout); + pub(crate) fn saw_bitfield_unit(&mut self, layout: Layout) { + debug!("saw bitfield unit for {}: {layout:?}", self.name); self.align_to_latest_field(layout); @@ -146,14 +131,12 @@ impl<'a> StructLayoutTracker<'a> { self.latest_field_layout = Some(layout); self.last_field_was_bitfield = true; - // NB: We intentionally don't update the max_field_align here, since our - // bitfields code doesn't necessarily guarantee it, so we need to - // actually generate the dummy alignment. + self.max_field_align = cmp::max(self.max_field_align, layout.align); } /// Returns a padding field if necessary for a given new field _before_ /// adding that field. - pub fn saw_field( + pub(crate) fn saw_field( &mut self, field_name: &str, field_ty: &Type, @@ -183,7 +166,7 @@ impl<'a> StructLayoutTracker<'a> { self.saw_field_with_layout(field_name, field_layout, field_offset) } - pub fn saw_field_with_layout( + pub(crate) fn saw_field_with_layout( &mut self, field_name: &str, field_layout: Layout, @@ -204,7 +187,10 @@ impl<'a> StructLayoutTracker<'a> { 0 } else if !self.is_packed { self.padding_bytes(field_layout) - } else if let Some(l) = self.known_type_layout { + } else if let Some(mut l) = self.known_type_layout { + if field_layout.align < l.align { + l.align = field_layout.align; + } self.padding_bytes(l) } else { 0 @@ -231,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 { @@ -252,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 ); @@ -268,7 +255,7 @@ impl<'a> StructLayoutTracker<'a> { padding_layout.map(|layout| self.padding_field(layout)) } - pub fn add_tail_padding( + pub(crate) fn add_tail_padding( &mut self, comp_name: &str, comp_layout: Layout, @@ -284,14 +271,18 @@ impl<'a> StructLayoutTracker<'a> { return None; } + // Also doesn't make sense for structs with flexible array members + if self.last_field_was_flexible_array { + return None; + } + if self.latest_offset == comp_layout.size { // This struct does not contain tail padding. return None; } 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 ); @@ -299,14 +290,11 @@ impl<'a> StructLayoutTracker<'a> { Some(self.padding_field(Layout::new(size, 0))) } - pub fn pad_struct( + pub(crate) fn pad_struct( &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!( @@ -322,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. @@ -346,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 { @@ -354,8 +342,8 @@ impl<'a> StructLayoutTracker<'a> { } } - pub fn requires_explicit_align(&self, layout: Layout) -> bool { - let repr_align = self.ctx.options().rust_features().repr_align; + pub(crate) fn requires_explicit_align(&self, layout: Layout) -> bool { + 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. @@ -379,42 +367,43 @@ 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(), ); self.max_field_align = cmp::max(self.max_field_align, layout.align); + let vis = super::access_specifier(self.visibility); + quote! { - pub #padding_field_name : #ty , + #vis #padding_field_name : #ty , } } /// 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 new file mode 100644 index 0000000000..3f95ac1e89 --- /dev/null +++ b/bindgen/deps.rs @@ -0,0 +1,61 @@ +/// Generating build depfiles from parsed bindings. +use std::{collections::BTreeSet, path::PathBuf}; + +#[derive(Clone, Debug)] +pub(crate) struct DepfileSpec { + pub output_module: String, + pub depfile_path: PathBuf, +} + +impl DepfileSpec { + pub fn write(&self, deps: &BTreeSet>) -> std::io::Result<()> { + std::fs::write(&self.depfile_path, self.to_string(deps)) + } + + fn to_string(&self, deps: &BTreeSet>) -> String { + // Transforms a string by escaping spaces and backslashes. + let escape = |s: &str| s.replace('\\', "\\\\").replace(' ', "\\ "); + + let mut buf = format!("{}:", escape(&self.output_module)); + for file in deps { + buf = format!("{buf} {}", escape(file)); + } + buf + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn escaping_depfile() { + let spec = DepfileSpec { + output_module: "Mod Name".to_owned(), + depfile_path: PathBuf::new(), + }; + + let deps: BTreeSet<_> = vec![ + r"/absolute/path".into(), + r"C:\win\absolute\path".into(), + r"../relative/path".into(), + r"..\win\relative\path".into(), + r"../path/with spaces/in/it".into(), + r"..\win\path\with spaces\in\it".into(), + r"path\with/mixed\separators".into(), + ] + .into_iter() + .collect(); + assert_eq!( + spec.to_string(&deps), + "Mod\\ Name: \ + ../path/with\\ spaces/in/it \ + ../relative/path \ + ..\\\\win\\\\path\\\\with\\ spaces\\\\in\\\\it \ + ..\\\\win\\\\relative\\\\path \ + /absolute/path \ + C:\\\\win\\\\absolute\\\\path \ + path\\\\with/mixed\\\\separators" + ); + } +} diff --git a/bindgen/diagnostics.rs b/bindgen/diagnostics.rs new file mode 100644 index 0000000000..f22402ac0e --- /dev/null +++ b/bindgen/diagnostics.rs @@ -0,0 +1,146 @@ +//! Types and function used to emit pretty diagnostics for `bindgen`. +//! +//! The entry point of this module is the [`Diagnostic`] type. + +use std::fmt::Write; +use std::io::{self, BufRead, BufReader}; +use std::{borrow::Cow, fs::File}; + +use annotate_snippets::{Renderer, Snippet}; + +pub(crate) use annotate_snippets::Level; + +/// A `bindgen` diagnostic. +#[derive(Default)] +pub(crate) struct Diagnostic<'a> { + title: Option<(Cow<'a, str>, Level)>, + slices: Vec>, + footer: Vec<(Cow<'a, str>, Level)>, +} + +impl<'a> Diagnostic<'a> { + /// Add a title to the diagnostic and set its type. + pub(crate) fn with_title( + &mut self, + title: impl Into>, + level: Level, + ) -> &mut Self { + self.title = Some((title.into(), level)); + self + } + + /// Add a slice of source code to the diagnostic. + pub(crate) fn add_slice(&mut self, slice: Slice<'a>) -> &mut Self { + self.slices.push(slice); + self + } + + /// Add a footer annotation to the diagnostic. This annotation will have its own type. + pub(crate) fn add_annotation( + &mut self, + msg: impl Into>, + level: Level, + ) -> &mut Self { + self.footer.push((msg.into(), level)); + self + } + + /// Print this diagnostic. + /// + /// The diagnostic is printed using `cargo:warning` if `bindgen` is being invoked by a build + /// script or using `eprintln` otherwise. + pub(crate) fn display(&self) { + std::thread_local! { + static INVOKED_BY_BUILD_SCRIPT: bool = std::env::var_os("CARGO_CFG_TARGET_ARCH").is_some(); + } + + let mut footer = vec![]; + let mut slices = vec![]; + let snippet = if let Some((msg, level)) = &self.title { + (*level).title(msg) + } else { + return; + }; + + for (msg, level) in &self.footer { + footer.push((*level).title(msg)); + } + + // add additional info that this is generated by bindgen + // so as to not confuse with rustc warnings + footer.push( + Level::Info.title("This diagnostic was generated by bindgen."), + ); + + for slice in &self.slices { + if let Some(source) = &slice.source { + let mut snippet = Snippet::source(source) + .line_start(slice.line.unwrap_or_default()); + if let Some(origin) = &slice.filename { + snippet = snippet.origin(origin); + } + slices.push(snippet); + } + } + + let renderer = Renderer::styled(); + let dl = renderer.render(snippet.snippets(slices).footers(footer)); + + if INVOKED_BY_BUILD_SCRIPT.with(Clone::clone) { + // This is just a hack which hides the `warning:` added by cargo at the beginning of + // every line. This should be fine as our diagnostics already have a colorful title. + // FIXME (pvdrz): Could it be that this doesn't work in other languages? + let hide_warning = "\r \r"; + let string = dl.to_string(); + for line in string.lines() { + println!("cargo:warning={hide_warning}{line}"); + } + } else { + eprintln!("{dl}\n"); + } + } +} + +/// A slice of source code. +#[derive(Default)] +pub(crate) struct Slice<'a> { + source: Option>, + filename: Option, + line: Option, +} + +impl<'a> Slice<'a> { + /// Set the source code. + pub(crate) fn with_source( + &mut self, + source: impl Into>, + ) -> &mut Self { + self.source = Some(source.into()); + self + } + + /// Set the file, line and column. + pub(crate) fn with_location( + &mut self, + mut name: String, + line: usize, + col: usize, + ) -> &mut Self { + write!(name, ":{line}:{col}").expect("Writing to a string cannot fail"); + self.filename = Some(name); + self.line = Some(line); + self + } +} + +pub(crate) fn get_line( + filename: &str, + line: usize, +) -> io::Result> { + let file = BufReader::new(File::open(filename)?); + if let Some(line) = file.lines().nth(line.wrapping_sub(1)) { + return line.map(Some); + } + + Ok(None) +} diff --git a/bindgen/extra_assertions.rs b/bindgen/extra_assertions.rs new file mode 100644 index 0000000000..8526fd42d2 --- /dev/null +++ b/bindgen/extra_assertions.rs @@ -0,0 +1,17 @@ +//! Macros for defining extra assertions that should only be checked in testing +//! and/or CI when the `__testing_only_extra_assertions` feature is enabled. + +/// Simple macro that forwards to assert! when using +/// `__testing_only_extra_assertions`. +macro_rules! extra_assert { + ( $cond:expr ) => { + if cfg!(feature = "__testing_only_extra_assertions") { + assert!($cond); + } + }; + ( $cond:expr , $( $arg:tt )+ ) => { + if cfg!(feature = "__testing_only_extra_assertions") { + assert!($cond, $( $arg )* ) + } + }; +} diff --git a/bindgen/features.rs b/bindgen/features.rs new file mode 100644 index 0000000000..04450bdee5 --- /dev/null +++ b/bindgen/features.rs @@ -0,0 +1,562 @@ +//! Contains code for selecting features + +#![deny(unused_extern_crates)] +#![deny(clippy::missing_docs_in_private_items)] +#![allow(deprecated)] + +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 $(($nightly_edition:literal))|* $(: #$issue:literal)?),* $(,)?} $(,)? + $( + $variant:ident($minor:literal) => {$($feature:ident $(($edition:literal))|* $(: #$pull:literal)?),* $(,)?}, + )* + $(,)? + ) => { + + 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),)* ")", + )])* + #[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!("Version 1.", stringify!($minor), " of Rust, which introduced the following features:")] + $(#[doc = concat!( + "- [`", stringify!($feature), "`]", + "(", $("https://github.com/rust-lang/rust/pull/", stringify!($pull),)* ")", + )])* + #[deprecated = "The use of this constant is deprecated, please use `RustTarget::stable` instead."] + pub const $variant: Self = Self(Version::Stable($minor, 0)); + )* + + const fn stable_releases() -> [(Self, u64); [$($minor,)*].len()] { + [$((Self::$variant, $minor),)*] + } + } + + #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] + pub(crate) struct RustFeatures { + $($(pub(crate) $feature: bool,)*)* + $(pub(crate) $nightly_feature: bool,)* + } + + 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.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 + } + } + }; +} + +// NOTE: When adding or removing features here, make sure to add the stabilization PR +// number for the feature if it has been stabilized or the tracking issue number if the feature is +// not stable. +define_rust_targets! { + Nightly => { + vectorcall_abi: #124485, + ptr_metadata: #81513, + layout_for_ptr: #69835, + }, + 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_51(51) => {}, +} + +/// Latest stable release of Rust that is supported by bindgen +pub const LATEST_STABLE_RUST: RustTarget = { + // FIXME: replace all this code by + // ``` + // RustTarget::stable_releases() + // .into_iter() + // .max_by_key(|(_, m)| m) + // .map(|(t, _)| t) + // .unwrap() + // ``` + // once those operations can be used in constants. + let targets = RustTarget::stable_releases(); + + let mut i = 0; + let mut latest_target = None; + let mut latest_minor = 0; + + while i < targets.len() { + let (target, minor) = targets[i]; + + if latest_minor < minor { + latest_minor = minor; + latest_target = Some(target); + } + + i += 1; + } + + match latest_target { + Some(target) => target, + None => unreachable!(), + } +}; + +/// 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(); + + 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]; + + 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(input: &str) -> Result { + if input == "nightly" { + return Ok(Self::Nightly); + } + + 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\"", + )); + } + + 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 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 { + Self::new_with_latest_edition(RustTarget::default()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn release_versions_for_editions() { + assert_eq!( + "1.51".parse::().unwrap().latest_edition(), + RustEdition::Edition2018 + ); + assert_eq!( + "1.59".parse::().unwrap().latest_edition(), + RustEdition::Edition2021 + ); + assert_eq!( + "1.85".parse::().unwrap().latest_edition(), + RustEdition::Edition2024 + ); + 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 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.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_invalid_target(input: &str) { + assert!( + input.parse::().is_err(), + "{input} should be an invalid target" + ); + } + + #[test] + 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 new file mode 100644 index 0000000000..7316950ba2 --- /dev/null +++ b/bindgen/ir/analysis/derive.rs @@ -0,0 +1,693 @@ +//! Determining which types for which we cannot emit `#[derive(Trait)]`. + +use std::fmt; + +use super::{generate_dependencies, ConstrainResult, MonotoneFramework}; +use crate::ir::analysis::has_vtable::HasVtable; +use crate::ir::comp::CompKind; +use crate::ir::context::{BindgenContext, ItemId}; +use crate::ir::derive::CanDerive; +use crate::ir::function::FunctionSig; +use crate::ir::item::{IsOpaque, Item}; +use crate::ir::layout::Layout; +use crate::ir::template::TemplateParameters; +use crate::ir::traversal::{EdgeKind, Trace}; +use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; +use crate::ir::ty::{Type, TypeKind}; +use crate::{Entry, HashMap, HashSet}; + +/// Which trait to consider when doing the `CannotDerive` analysis. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum DeriveTrait { + /// The `Copy` trait. + Copy, + /// The `Debug` trait. + Debug, + /// The `Default` trait. + Default, + /// The `Hash` trait. + Hash, + /// The `PartialEq` and `PartialOrd` traits. + PartialEqOrPartialOrd, +} + +/// An analysis that finds for each IR item whether a trait cannot be derived. +/// +/// We use the monotone constraint function `cannot_derive`, defined as follows +/// for type T: +/// +/// * If T is Opaque and the layout of the type is known, get this layout as an +/// opaquetype and check whether it can derive using trivial checks. +/// +/// * If T is Array, a trait cannot be derived if the array is incomplete, +/// if the length of the array is larger than the limit (unless the trait +/// allows it), or the trait cannot be derived for the type of data the array +/// contains. +/// +/// * If T is Vector, a trait cannot be derived if the trait cannot be derived +/// for the type of data the vector contains. +/// +/// * If T is a type alias, a templated alias or an indirection to another type, +/// the trait cannot be derived if the trait cannot be derived for type T +/// refers to. +/// +/// * If T is a compound type, the trait cannot be derived if the trait cannot +/// be derived for any of its base members or fields. +/// +/// * If T is an instantiation of an abstract template definition, the trait +/// cannot be derived if any of the template arguments or template definition +/// cannot derive the trait. +/// +/// * For all other (simple) types, compiler and standard library limitations +/// dictate whether the trait is implemented. +#[derive(Debug, Clone)] +pub(crate) struct CannotDerive<'ctx> { + ctx: &'ctx BindgenContext, + + derive_trait: DeriveTrait, + + // The incremental result of this analysis's computation. + // Contains information whether particular item can derive `derive_trait` + can_derive: HashMap, + + // Dependencies saying that if a key ItemId has been inserted into the + // `cannot_derive_partialeq_or_partialord` set, then each of the ids + // in Vec need to be considered again. + // + // This is a subset of the natural IR graph with reversed edges, where we + // only include the edges from the IR graph that can affect whether a type + // can derive `derive_trait`. + dependencies: HashMap>, +} + +type EdgePredicate = fn(EdgeKind) -> bool; + +fn consider_edge_default(kind: EdgeKind) -> bool { + match kind { + // These are the only edges that can affect whether a type can derive + EdgeKind::BaseMember | + EdgeKind::Field | + EdgeKind::TypeReference | + EdgeKind::VarType | + EdgeKind::TemplateArgument | + EdgeKind::TemplateDeclaration | + EdgeKind::TemplateParameterDefinition => true, + + EdgeKind::Constructor | + EdgeKind::Destructor | + EdgeKind::FunctionReturn | + EdgeKind::FunctionParameter | + EdgeKind::InnerType | + EdgeKind::InnerVar | + EdgeKind::Method | + EdgeKind::Generic => false, + } +} + +impl CannotDerive<'_> { + fn insert>( + &mut self, + id: Id, + can_derive: CanDerive, + ) -> ConstrainResult { + let id = id.into(); + trace!( + "inserting {id:?} can_derive<{}>={can_derive:?}", + self.derive_trait, + ); + + if let CanDerive::Yes = can_derive { + return ConstrainResult::Same; + } + + match self.can_derive.entry(id) { + Entry::Occupied(mut entry) => { + if *entry.get() < can_derive { + entry.insert(can_derive); + ConstrainResult::Changed + } else { + ConstrainResult::Same + } + } + Entry::Vacant(entry) => { + entry.insert(can_derive); + ConstrainResult::Changed + } + } + } + + fn constrain_type(&mut self, item: &Item, ty: &Type) -> CanDerive { + if !self.ctx.allowlisted_items().contains(&item.id()) { + let can_derive = self + .ctx + .blocklisted_type_implements_trait(item, self.derive_trait); + match can_derive { + CanDerive::Yes => trace!( + " blocklisted type explicitly implements {}", + self.derive_trait + ), + CanDerive::Manually => trace!( + " blocklisted type requires manual implementation of {}", + self.derive_trait + ), + CanDerive::No => trace!( + " cannot derive {} for blocklisted type", + self.derive_trait + ), + } + return can_derive; + } + + if self.derive_trait.not_by_name(self.ctx, item) { + trace!( + " cannot derive {} for explicitly excluded type", + self.derive_trait + ); + return CanDerive::No; + } + + trace!("ty: {ty:?}"); + if item.is_opaque(self.ctx, &()) { + if !self.derive_trait.can_derive_union() && + ty.is_union() && + self.ctx.options().untagged_union + { + trace!( + " cannot derive {} for Rust unions", + self.derive_trait + ); + return CanDerive::No; + } + + trace!( + " we can trivially derive {} for the layout", + self.derive_trait + ); + return CanDerive::Yes; + } + + match *ty.kind() { + // Handle the simple cases. These can derive traits without further + // information. + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Complex(..) | + TypeKind::Float(..) | + TypeKind::Enum(..) | + TypeKind::TypeParam | + TypeKind::UnresolvedTypeRef(..) | + TypeKind::Reference(..) | + TypeKind::ObjCInterface(..) | + TypeKind::ObjCId | + 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); + if let TypeKind::Function(ref sig) = *inner_type.kind() { + self.derive_trait.can_derive_fnptr(sig) + } else { + self.derive_trait.can_derive_pointer() + } + } + TypeKind::Function(ref sig) => { + self.derive_trait.can_derive_fnptr(sig) + } + + // Complex cases need more information + TypeKind::Array(t, len) => { + let inner_type = + self.can_derive.get(&t.into()).copied().unwrap_or_default(); + if inner_type != CanDerive::Yes { + trace!( + " arrays of T for which we cannot derive {} \ + also cannot derive {}", + self.derive_trait, + self.derive_trait + ); + return CanDerive::No; + } + + if len == 0 && !self.derive_trait.can_derive_incomplete_array() + { + trace!( + " cannot derive {} for incomplete arrays", + self.derive_trait + ); + return CanDerive::No; + } + + if self.derive_trait.can_derive_large_array(self.ctx) { + trace!(" array can derive {}", self.derive_trait); + return CanDerive::Yes; + } + + if len > RUST_DERIVE_IN_ARRAY_LIMIT { + trace!( + " array is too large to derive {}, but it may be implemented", self.derive_trait + ); + return CanDerive::Manually; + } + trace!( + " array is small enough to derive {}", + self.derive_trait + ); + CanDerive::Yes + } + TypeKind::Vector(t, len) => { + let inner_type = + self.can_derive.get(&t.into()).copied().unwrap_or_default(); + if inner_type != CanDerive::Yes { + trace!( + " vectors of T for which we cannot derive {} \ + also cannot derive {}", + self.derive_trait, + self.derive_trait + ); + return CanDerive::No; + } + assert_ne!(len, 0, "vectors cannot have zero length"); + self.derive_trait.can_derive_vector() + } + + TypeKind::Comp(ref info) => { + assert!( + !info.has_non_type_template_params(), + "The early ty.is_opaque check should have handled this case" + ); + + if !self.derive_trait.can_derive_compound_forward_decl() && + info.is_forward_declaration() + { + trace!( + " cannot derive {} for forward decls", + self.derive_trait + ); + return CanDerive::No; + } + + // NOTE: Take into account that while unions in C and C++ are copied by + // default, the may have an explicit destructor in C++, so we can't + // defer this check just for the union case. + if !self.derive_trait.can_derive_compound_with_destructor() && + self.ctx.lookup_has_destructor( + item.id().expect_type_id(self.ctx), + ) + { + trace!( + " comp has destructor which cannot derive {}", + self.derive_trait + ); + return CanDerive::No; + } + + if info.kind() == CompKind::Union { + if self.derive_trait.can_derive_union() { + if self.ctx.options().untagged_union && + // https://github.com/rust-lang/rust/issues/36640 + (!info.self_template_params(self.ctx).is_empty() || + !item.all_template_params(self.ctx).is_empty()) + { + trace!( + " cannot derive {} for Rust union because issue 36640", self.derive_trait + ); + return CanDerive::No; + } + // fall through to be same as non-union handling + } else { + if self.ctx.options().untagged_union { + trace!( + " cannot derive {} for Rust unions", + self.derive_trait + ); + return CanDerive::No; + } + + trace!( + " union layout can trivially derive {}", + self.derive_trait + ); + return CanDerive::Yes; + } + } + + if !self.derive_trait.can_derive_compound_with_vtable() && + item.has_vtable(self.ctx) + { + trace!( + " cannot derive {} for comp with vtable", + self.derive_trait + ); + return CanDerive::No; + } + + // Bitfield units are always represented as arrays of u8, but + // they're not traced as arrays, so we need to check here + // instead. + if !self.derive_trait.can_derive_large_array(self.ctx) && + info.has_too_large_bitfield_unit() && + !item.is_opaque(self.ctx, &()) + { + trace!( + " cannot derive {} for comp with too large bitfield unit", + self.derive_trait + ); + return CanDerive::No; + } + + let pred = self.derive_trait.consider_edge_comp(); + self.constrain_join(item, pred) + } + + TypeKind::ResolvedTypeRef(..) | + TypeKind::TemplateAlias(..) | + TypeKind::Alias(..) | + TypeKind::BlockPointer(..) => { + let pred = self.derive_trait.consider_edge_typeref(); + self.constrain_join(item, pred) + } + + TypeKind::TemplateInstantiation(..) => { + let pred = self.derive_trait.consider_edge_tmpl_inst(); + self.constrain_join(item, pred) + } + + TypeKind::Opaque => unreachable!( + "The early ty.is_opaque check should have handled this case" + ), + } + } + + fn constrain_join( + &mut self, + item: &Item, + consider_edge: EdgePredicate, + ) -> CanDerive { + let mut candidate = None; + + item.trace( + self.ctx, + &mut |sub_id, edge_kind| { + // Ignore ourselves, since union with ourself is a + // no-op. Ignore edges that aren't relevant to the + // analysis. + if sub_id == item.id() || !consider_edge(edge_kind) { + return; + } + + let can_derive = self.can_derive + .get(&sub_id) + .copied() + .unwrap_or_default(); + + match can_derive { + 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; + }, + &(), + ); + + if candidate.is_none() { + trace!( + " can derive {} because there are no members", + self.derive_trait + ); + } + candidate.unwrap_or_default() + } +} + +impl DeriveTrait { + 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), + DeriveTrait::Default => ctx.no_default_by_name(item), + DeriveTrait::Hash => ctx.no_hash_by_name(item), + DeriveTrait::PartialEqOrPartialOrd => { + ctx.no_partialeq_by_name(item) + } + } + } + + 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 { + match self { + DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, + _ => |kind| kind == EdgeKind::TypeReference, + } + } + + fn consider_edge_tmpl_inst(self) -> EdgePredicate { + match self { + DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, + _ => |kind| { + matches!( + kind, + EdgeKind::TemplateArgument | EdgeKind::TemplateDeclaration + ) + }, + } + } + + fn can_derive_large_array(self, _: &BindgenContext) -> bool { + !matches!(self, DeriveTrait::Default) + } + + fn can_derive_union(self) -> bool { + matches!(self, DeriveTrait::Copy) + } + + fn can_derive_compound_with_destructor(self) -> bool { + !matches!(self, DeriveTrait::Copy) + } + + fn can_derive_compound_with_vtable(self) -> bool { + !matches!(self, DeriveTrait::Default) + } + + fn can_derive_compound_forward_decl(self) -> bool { + matches!(self, DeriveTrait::Copy | DeriveTrait::Debug) + } + + fn can_derive_incomplete_array(self) -> bool { + !matches!( + self, + DeriveTrait::Copy | + DeriveTrait::Hash | + DeriveTrait::PartialEqOrPartialOrd + ) + } + + 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}"); + CanDerive::Yes + } + (DeriveTrait::Debug, false) => { + trace!(" function pointer cannot derive {self}, but it may be implemented"); + CanDerive::Manually + } + (_, false) => { + trace!(" function pointer cannot derive {self}"); + CanDerive::No + } + } + } + + 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 { + 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 { + match (self, kind) { + // === Default === + ( + 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 + } + (DeriveTrait::Default, TypeKind::UnresolvedTypeRef(..)) => { + unreachable!( + "Type with unresolved type ref can't reach derive default" + ) + } + // === Hash === + ( + DeriveTrait::Hash, + TypeKind::Float(..) | TypeKind::Complex(..), + ) => { + trace!(" float cannot derive Hash"); + CanDerive::No + } + // === others === + _ => { + trace!(" simple type that can always derive {self}"); + CanDerive::Yes + } + } + } +} + +impl fmt::Display for DeriveTrait { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let s = match self { + DeriveTrait::Copy => "Copy", + DeriveTrait::Debug => "Debug", + DeriveTrait::Default => "Default", + DeriveTrait::Hash => "Hash", + DeriveTrait::PartialEqOrPartialOrd => "PartialEq/PartialOrd", + }; + s.fmt(f) + } +} + +impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { + type Node = ItemId; + type Extra = (&'ctx BindgenContext, DeriveTrait); + type Output = HashMap; + + fn new( + (ctx, derive_trait): (&'ctx BindgenContext, DeriveTrait), + ) -> CannotDerive<'ctx> { + let can_derive = HashMap::default(); + let dependencies = generate_dependencies(ctx, consider_edge_default); + + CannotDerive { + ctx, + derive_trait, + can_derive, + dependencies, + } + } + + fn initial_worklist(&self) -> Vec { + // The transitive closure of all allowlisted items, including explicitly + // blocklisted items. + self.ctx + .allowlisted_items() + .iter() + .copied() + .flat_map(|i| { + let mut reachable = vec![i]; + i.trace( + self.ctx, + &mut |s, _| { + reachable.push(s); + }, + &(), + ); + reachable + }) + .collect() + } + + fn constrain(&mut self, id: ItemId) -> ConstrainResult { + trace!("constrain: {id:?}"); + + if let Some(CanDerive::No) = self.can_derive.get(&id) { + trace!(" already know it cannot derive {}", self.derive_trait); + return ConstrainResult::Same; + } + + let item = self.ctx.resolve_item(id); + let can_derive = match item.as_type() { + Some(ty) => { + let mut can_derive = self.constrain_type(item, ty); + if let CanDerive::Yes = can_derive { + 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).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 + // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations + // into the IR and computed them before this analysis, then we could + // be precise rather than conservative here. + can_derive = CanDerive::Manually; + } + } + can_derive + } + None => self.constrain_join(item, consider_edge_default), + }; + + self.insert(id, can_derive) + } + + fn each_depending_on(&self, id: ItemId, mut f: F) + where + F: FnMut(ItemId), + { + if let Some(edges) = self.dependencies.get(&id) { + for item in edges { + trace!("enqueue {item:?} into worklist"); + f(*item); + } + } + } +} + +impl<'ctx> From> for HashMap { + fn from(analysis: CannotDerive<'ctx>) -> Self { + extra_assert!(analysis + .can_derive + .values() + .all(|v| *v != CanDerive::Yes)); + + analysis.can_derive + } +} + +/// Convert a `HashMap` into a `HashSet`. +/// +/// Elements that are not `CanDerive::Yes` are kept in the set, so that it +/// represents all items that cannot derive. +pub(crate) fn as_cannot_derive_set( + can_derive: HashMap, +) -> HashSet { + can_derive + .into_iter() + .filter_map(|(k, v)| if v == CanDerive::Yes { None } else { Some(k) }) + .collect() +} diff --git a/src/ir/analysis/has_destructor.rs b/bindgen/ir/analysis/has_destructor.rs similarity index 93% rename from src/ir/analysis/has_destructor.rs rename to bindgen/ir/analysis/has_destructor.rs index 74fd73d14e..44ef33c21b 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/bindgen/ir/analysis/has_destructor.rs @@ -22,7 +22,7 @@ use crate::{HashMap, HashSet}; /// * If T is the type of a field, that field has a destructor if it's not a bitfield, /// and if T has a destructor. #[derive(Debug, Clone)] -pub struct HasDestructorAnalysis<'ctx> { +pub(crate) struct HasDestructorAnalysis<'ctx> { ctx: &'ctx BindgenContext, // The incremental result of this analysis's computation. Everything in this @@ -39,7 +39,7 @@ pub 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/src/ir/analysis/has_float.rs b/bindgen/ir/analysis/has_float.rs similarity index 91% rename from src/ir/analysis/has_float.rs rename to bindgen/ir/analysis/has_float.rs index bbf2126f70..e2463ccb96 100644 --- a/src/ir/analysis/has_float.rs +++ b/bindgen/ir/analysis/has_float.rs @@ -22,7 +22,7 @@ use crate::{HashMap, HashSet}; /// float if any of the template arguments or template definition /// has. #[derive(Debug, Clone)] -pub struct HasFloat<'ctx> { +pub(crate) struct HasFloat<'ctx> { ctx: &'ctx BindgenContext, // The incremental result of this analysis's computation. Everything in this @@ -39,7 +39,7 @@ pub 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/src/ir/analysis/has_type_param_in_array.rs b/bindgen/ir/analysis/has_type_param_in_array.rs similarity index 85% rename from src/ir/analysis/has_type_param_in_array.rs rename to bindgen/ir/analysis/has_type_param_in_array.rs index aa52304758..687f81560c 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/bindgen/ir/analysis/has_type_param_in_array.rs @@ -17,12 +17,12 @@ use crate::{HashMap, HashSet}; /// * If T is a type alias, a templated alias or an indirection to another type, /// it has type parameter in array if the type T refers to has. /// * If T is a compound type, it has array if any of base memter or field -/// has type paramter in array. +/// has type parameter in array. /// * If T is an instantiation of an abstract template definition, T has /// type parameter in array if any of the template arguments or template definition /// has. #[derive(Debug, Clone)] -pub struct HasTypeParameterInArray<'ctx> { +pub(crate) struct HasTypeParameterInArray<'ctx> { ctx: &'ctx BindgenContext, // The incremental result of this analysis's computation. Everything in this @@ -39,7 +39,7 @@ pub 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/src/ir/analysis/has_vtable.rs b/bindgen/ir/analysis/has_vtable.rs similarity index 89% rename from src/ir/analysis/has_vtable.rs rename to bindgen/ir/analysis/has_vtable.rs index 8ac47a65da..b8ecc6088e 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/bindgen/ir/analysis/has_vtable.rs @@ -9,9 +9,10 @@ use std::cmp; use std::ops; /// The result of the `HasVtableAnalysis` for an individual item. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum HasVtableResult { +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)] +pub(crate) enum HasVtableResult { /// The item does not have a vtable pointer. + #[default] No, /// The item has a vtable and the actual vtable pointer is within this item. @@ -22,15 +23,9 @@ pub enum HasVtableResult { BaseHasVtable, } -impl Default for HasVtableResult { - fn default() -> Self { - HasVtableResult::No - } -} - impl HasVtableResult { /// Take the least upper bound of `self` and `rhs`. - pub fn join(self, rhs: Self) -> Self { + pub(crate) fn join(self, rhs: Self) -> Self { cmp::max(self, rhs) } } @@ -45,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); } } @@ -60,7 +55,7 @@ impl ops::BitOrAssign for HasVtableResult { /// * If T is an instantiation of an abstract template definition, T has /// vtable if template definition has vtable #[derive(Debug, Clone)] -pub struct HasVtableAnalysis<'ctx> { +pub(crate) struct HasVtableAnalysis<'ctx> { ctx: &'ctx BindgenContext, // The incremental result of this analysis's computation. Everything in this @@ -77,7 +72,7 @@ pub 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. @@ -123,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), } } } @@ -147,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. @@ -181,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 { @@ -205,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); } } @@ -228,9 +222,9 @@ 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 trait HasVtable { +pub(crate) trait HasVtable { /// Return `true` if this thing has vtable, `false` otherwise. fn has_vtable(&self, ctx: &BindgenContext) -> bool; diff --git a/bindgen/ir/analysis/mod.rs b/bindgen/ir/analysis/mod.rs new file mode 100644 index 0000000000..74a305edfb --- /dev/null +++ b/bindgen/ir/analysis/mod.rs @@ -0,0 +1,395 @@ +//! Fix-point analyses on the IR using the "monotone framework". +//! +//! A lattice is a set with a partial ordering between elements, where there is +//! a single least upper bound and a single greatest least bound for every +//! subset. We are dealing with finite lattices, which means that it has a +//! finite number of elements, and it follows that there exists a single top and +//! a single bottom member of the lattice. For example, the power set of a +//! finite set forms a finite lattice where partial ordering is defined by set +//! inclusion, that is `a <= b` if `a` is a subset of `b`. Here is the finite +//! lattice constructed from the set {0,1,2}: +//! +//! ```text +//! .----- Top = {0,1,2} -----. +//! / | \ +//! / | \ +//! / | \ +//! {0,1} -------. {0,2} .--------- {1,2} +//! | \ / \ / | +//! | / \ | +//! | / \ / \ | +//! {0} --------' {1} `---------- {2} +//! \ | / +//! \ | / +//! \ | / +//! `------ Bottom = {} ------' +//! ``` +//! +//! A monotone function `f` is a function where if `x <= y`, then it holds that +//! `f(x) <= f(y)`. It should be clear that running a monotone function to a +//! fix-point on a finite lattice will always terminate: `f` can only "move" +//! along the lattice in a single direction, and therefore can only either find +//! a fix-point in the middle of the lattice or continue to the top or bottom +//! depending if it is ascending or descending the lattice respectively. +//! +//! For a deeper introduction to the general form of this kind of analysis, see +//! [Static Program Analysis by Anders Møller and Michael I. Schwartzbach][spa]. +//! +//! [spa]: https://cs.au.dk/~amoeller/spa/spa.pdf + +// Re-export individual analyses. +mod template_params; +pub(crate) use self::template_params::UsedTemplateParameters; +mod derive; +pub use self::derive::DeriveTrait; +pub(crate) use self::derive::{as_cannot_derive_set, CannotDerive}; +mod has_vtable; +pub(crate) use self::has_vtable::{ + HasVtable, HasVtableAnalysis, HasVtableResult, +}; +mod has_destructor; +pub(crate) use self::has_destructor::HasDestructorAnalysis; +mod has_type_param_in_array; +pub(crate) use self::has_type_param_in_array::HasTypeParameterInArray; +mod has_float; +pub(crate) use self::has_float::HasFloat; +mod sizedness; +pub(crate) use self::sizedness::{ + Sizedness, SizednessAnalysis, SizednessResult, +}; + +use crate::ir::context::{BindgenContext, ItemId}; + +use crate::ir::traversal::{EdgeKind, Trace}; +use crate::HashMap; +use std::fmt; +use std::ops; + +/// An analysis in the monotone framework. +/// +/// Implementors of this trait must maintain the following two invariants: +/// +/// 1. The concrete data must be a member of a finite-height lattice. +/// 2. The concrete `constrain` method must be monotone: that is, +/// if `x <= y`, then `constrain(x) <= constrain(y)`. +/// +/// If these invariants do not hold, iteration to a fix-point might never +/// complete. +/// +/// For a simple example analysis, see the `ReachableFrom` type in the `tests` +/// module below. +pub(crate) trait MonotoneFramework: Sized + fmt::Debug { + /// The type of node in our dependency graph. + /// + /// This is just generic (and not `ItemId`) so that we can easily unit test + /// without constructing real `Item`s and their `ItemId`s. + type Node: Copy; + + /// Any extra data that is needed during computation. + /// + /// Again, this is just generic (and not `&BindgenContext`) so that we can + /// easily unit test without constructing real `BindgenContext`s full of + /// real `Item`s and real `ItemId`s. + type Extra: Sized; + + /// The final output of this analysis. Once we have reached a fix-point, we + /// convert `self` into this type, and return it as the final result of the + /// analysis. + type Output: From + fmt::Debug; + + /// Construct a new instance of this analysis. + fn new(extra: Self::Extra) -> Self; + + /// Get the initial set of nodes from which to start the analysis. Unless + /// you are sure of some domain-specific knowledge, this should be the + /// complete set of nodes. + fn initial_worklist(&self) -> Vec; + + /// Update the analysis for the given node. + /// + /// If this results in changing our internal state (ie, we discovered that + /// we have not reached a fix-point and iteration should continue), return + /// `ConstrainResult::Changed`. Otherwise, return `ConstrainResult::Same`. + /// When `constrain` returns `ConstrainResult::Same` for all nodes in the + /// set, we have reached a fix-point and the analysis is complete. + fn constrain(&mut self, node: Self::Node) -> ConstrainResult; + + /// For each node `d` that depends on the given `node`'s current answer when + /// running `constrain(d)`, call `f(d)`. This informs us which new nodes to + /// queue up in the worklist when `constrain(node)` reports updated + /// information. + fn each_depending_on(&self, node: Self::Node, f: F) + where + F: FnMut(Self::Node); +} + +/// Whether an analysis's `constrain` function modified the incremental results +/// or not. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +pub(crate) enum ConstrainResult { + /// The incremental results were updated, and the fix-point computation + /// should continue. + Changed, + + /// The incremental results were not updated. + #[default] + Same, +} + +impl ops::BitOr for ConstrainResult { + type Output = Self; + + fn bitor(self, rhs: ConstrainResult) -> Self::Output { + if self == ConstrainResult::Changed || rhs == ConstrainResult::Changed { + ConstrainResult::Changed + } else { + ConstrainResult::Same + } + } +} + +impl ops::BitOrAssign for ConstrainResult { + fn bitor_assign(&mut self, rhs: ConstrainResult) { + *self = *self | rhs; + } +} + +/// Run an analysis in the monotone framework. +pub(crate) fn analyze(extra: Analysis::Extra) -> Analysis::Output +where + Analysis: MonotoneFramework, +{ + let mut analysis = Analysis::new(extra); + let mut worklist = analysis.initial_worklist(); + + while let Some(node) = worklist.pop() { + if let ConstrainResult::Changed = analysis.constrain(node) { + analysis.each_depending_on(node, |needs_work| { + worklist.push(needs_work); + }); + } + } + + analysis.into() +} + +/// Generate the dependency map for analysis +pub(crate) fn generate_dependencies( + ctx: &BindgenContext, + consider_edge: F, +) -> HashMap> +where + F: Fn(EdgeKind) -> bool, +{ + let mut dependencies = HashMap::default(); + + for &item in ctx.allowlisted_items() { + dependencies.entry(item).or_insert_with(Vec::new); + + { + // We reverse our natural IR graph edges to find dependencies + // between nodes. + item.trace( + ctx, + &mut |sub_item: ItemId, edge_kind| { + if ctx.allowlisted_items().contains(&sub_item) && + consider_edge(edge_kind) + { + dependencies + .entry(sub_item) + .or_insert_with(Vec::new) + .push(item); + } + }, + &(), + ); + } + } + dependencies +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::HashSet; + + // Here we find the set of nodes that are reachable from any given + // node. This is a lattice mapping nodes to subsets of all nodes. Our join + // function is set union. + // + // This is our test graph: + // + // +---+ +---+ + // | | | | + // | 1 | .----| 2 | + // | | | | | + // +---+ | +---+ + // | | ^ + // | | | + // | +---+ '------' + // '----->| | + // | 3 | + // .------| |------. + // | +---+ | + // | ^ | + // v | v + // +---+ | +---+ +---+ + // | | | | | | | + // | 4 | | | 5 |--->| 6 | + // | | | | | | | + // +---+ | +---+ +---+ + // | | | | + // | | | v + // | +---+ | +---+ + // | | | | | | + // '----->| 7 |<-----' | 8 | + // | | | | + // +---+ +---+ + // + // And here is the mapping from a node to the set of nodes that are + // reachable from it within the test graph: + // + // 1: {3,4,5,6,7,8} + // 2: {2} + // 3: {3,4,5,6,7,8} + // 4: {3,4,5,6,7,8} + // 5: {3,4,5,6,7,8} + // 6: {8} + // 7: {3,4,5,6,7,8} + // 8: {} + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] + struct Node(usize); + + #[derive(Clone, Debug, Default, PartialEq, Eq)] + struct Graph(HashMap>); + + impl Graph { + fn make_test_graph() -> Graph { + let mut g = Graph::default(); + g.0.insert(Node(1), vec![Node(3)]); + g.0.insert(Node(2), vec![Node(2)]); + g.0.insert(Node(3), vec![Node(4), Node(5)]); + g.0.insert(Node(4), vec![Node(7)]); + g.0.insert(Node(5), vec![Node(6), Node(7)]); + g.0.insert(Node(6), vec![Node(8)]); + g.0.insert(Node(7), vec![Node(3)]); + g.0.insert(Node(8), vec![]); + g + } + + fn reverse(&self) -> Graph { + let mut reversed = Graph::default(); + for (node, edges) in &self.0 { + reversed.0.entry(*node).or_insert_with(Vec::new); + for referent in edges { + reversed + .0 + .entry(*referent) + .or_insert_with(Vec::new) + .push(*node); + } + } + reversed + } + } + + #[derive(Clone, Debug, PartialEq, Eq)] + struct ReachableFrom<'a> { + reachable: HashMap>, + graph: &'a Graph, + reversed: Graph, + } + + impl<'a> MonotoneFramework for ReachableFrom<'a> { + type Node = Node; + type Extra = &'a Graph; + type Output = HashMap>; + + fn new(graph: &'a Graph) -> Self { + let reversed = graph.reverse(); + ReachableFrom { + reachable: Default::default(), + graph, + reversed, + } + } + + fn initial_worklist(&self) -> Vec { + self.graph.0.keys().copied().collect() + } + + fn constrain(&mut self, node: Node) -> ConstrainResult { + // The set of nodes reachable from a node `x` is + // + // reachable(x) = s_0 U s_1 U ... U reachable(s_0) U reachable(s_1) U ... + // + // where there exist edges from `x` to each of `s_0, s_1, ...`. + // + // Yes, what follows is a **terribly** inefficient set union + // implementation. Don't copy this code outside of this test! + + let original_size = self.reachable.entry(node).or_default().len(); + + for sub_node in &self.graph.0[&node] { + self.reachable.get_mut(&node).unwrap().insert(*sub_node); + + let sub_reachable = + self.reachable.entry(*sub_node).or_default().clone(); + + for transitive in sub_reachable { + self.reachable.get_mut(&node).unwrap().insert(transitive); + } + } + + let new_size = self.reachable[&node].len(); + if original_size == new_size { + ConstrainResult::Same + } else { + ConstrainResult::Changed + } + } + + fn each_depending_on(&self, node: Node, mut f: F) + where + F: FnMut(Node), + { + for dep in &self.reversed.0[&node] { + f(*dep); + } + } + } + + impl<'a> From> for HashMap> { + fn from(reachable: ReachableFrom<'a>) -> Self { + reachable.reachable + } + } + + #[test] + fn monotone() { + let g = Graph::make_test_graph(); + let reachable = analyze::(&g); + println!("reachable = {reachable:#?}"); + + fn nodes(nodes: A) -> HashSet + where + A: AsRef<[usize]>, + { + nodes.as_ref().iter().copied().map(Node).collect() + } + + let mut expected = HashMap::default(); + expected.insert(Node(1), nodes([3, 4, 5, 6, 7, 8])); + expected.insert(Node(2), nodes([2])); + expected.insert(Node(3), nodes([3, 4, 5, 6, 7, 8])); + expected.insert(Node(4), nodes([3, 4, 5, 6, 7, 8])); + expected.insert(Node(5), nodes([3, 4, 5, 6, 7, 8])); + 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:#?}"); + + assert_eq!(reachable, expected); + } +} diff --git a/src/ir/analysis/sizedness.rs b/bindgen/ir/analysis/sizedness.rs similarity index 92% rename from src/ir/analysis/sizedness.rs rename to bindgen/ir/analysis/sizedness.rs index 251c3747b2..ce3c2c3da1 100644 --- a/src/ir/analysis/sizedness.rs +++ b/bindgen/ir/analysis/sizedness.rs @@ -24,13 +24,14 @@ use std::{cmp, ops}; /// /// We initially assume that all types are `ZeroSized` and then update our /// understanding as we learn more about each type. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum SizednessResult { +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)] +pub(crate) enum SizednessResult { /// The type is zero-sized. /// /// This means that if it is a C++ type, and is not being used as a base /// member, then we must add an `_address` byte to enforce the /// unique-address-per-distinct-object-instance rule. + #[default] ZeroSized, /// Whether this type is zero-sized or not depends on whether a type @@ -52,7 +53,7 @@ pub enum SizednessResult { /// have an `_address` byte inserted. /// /// We don't properly handle this situation correctly right now: - /// https://github.com/rust-lang/rust-bindgen/issues/586 + /// DependsOnTypeParam, /// Has some size that is known to be greater than zero. That doesn't mean @@ -62,15 +63,9 @@ pub enum SizednessResult { NonZeroSized, } -impl Default for SizednessResult { - fn default() -> Self { - SizednessResult::ZeroSized - } -} - impl SizednessResult { /// Take the least upper bound of `self` and `rhs`. - pub fn join(self, rhs: Self) -> Self { + pub(crate) fn join(self, rhs: Self) -> Self { cmp::max(self, rhs) } } @@ -85,24 +80,24 @@ 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); } } /// An analysis that computes the sizedness of all types. /// /// * For types with known sizes -- for example pointers, scalars, etc... -- -/// they are assigned `NonZeroSized`. +/// they are assigned `NonZeroSized`. /// /// * For compound structure types with one or more fields, they are assigned -/// `NonZeroSized`. +/// `NonZeroSized`. /// /// * For compound structure types without any fields, the results of the bases -/// are `join`ed. +/// are `join`ed. /// /// * For type parameters, `DependsOnTypeParam` is assigned. #[derive(Debug)] -pub struct SizednessAnalysis<'ctx> { +pub(crate) struct SizednessAnalysis<'ctx> { ctx: &'ctx BindgenContext, dependencies: HashMap>, // Incremental results of the analysis. Missing entries are implicitly @@ -110,7 +105,7 @@ pub 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. @@ -132,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; @@ -155,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), } } } @@ -196,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; } @@ -327,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); } } @@ -346,11 +338,11 @@ impl<'ctx> From> for HashMap { } } -/// A convenience trait for querying whether some type or id is sized. +/// A convenience trait for querying whether some type or ID is sized. /// /// This is not for _computing_ whether the thing is sized, it is for looking up /// the results of the `Sizedness` analysis's computations for a specific thing. -pub trait Sizedness { +pub(crate) trait Sizedness { /// Get the sizedness of this type. fn sizedness(&self, ctx: &BindgenContext) -> SizednessResult; diff --git a/src/ir/analysis/template_params.rs b/bindgen/ir/analysis/template_params.rs similarity index 94% rename from src/ir/analysis/template_params.rs rename to bindgen/ir/analysis/template_params.rs index e88b774dee..df8f861cfe 100644 --- a/src/ir/analysis/template_params.rs +++ b/bindgen/ir/analysis/template_params.rs @@ -14,7 +14,7 @@ //! If we generate the naive Rust code for this alias, we get: //! //! ```ignore -//! pub type Fml = ::std::os::raw::int; +//! pub(crate) type Fml = ::std::os::raw::int; //! ``` //! //! And this is rejected by `rustc` due to the unused type parameter. @@ -124,8 +124,8 @@ use crate::{HashMap, HashSet}; /// ``` /// /// * Finally, for all other IR item kinds, we use our lattice's `join` -/// operation: set union with each successor of the given item's template -/// parameter usage: +/// operation: set union with each successor of the given item's template +/// parameter usage: /// /// ```ignore /// template_param_usage(v) = @@ -146,7 +146,7 @@ use crate::{HashMap, HashSet}; /// specially; see `constrain_instantiation_of_blocklisted_template` and its /// documentation for details. #[derive(Debug, Clone)] -pub struct UsedTemplateParameters<'ctx> { +pub(crate) struct UsedTemplateParameters<'ctx> { ctx: &'ctx BindgenContext, // The Option is only there for temporary moves out of the hash map. See the @@ -161,7 +161,7 @@ pub 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,14 +319,13 @@ impl<'ctx> UsedTemplateParameters<'ctx> { arg's used template param set should be \ `Some`", ) - .iter() - .cloned(); + .iter(); used_by_this_id.extend(used_by_arg); } } } - /// The join operation on our lattice: the set union of all of this id's + /// The join operation on our lattice: the set union of all of this ID's /// successors. fn constrain_join(&self, used_by_this_id: &mut ItemSet, item: &Item) { trace!(" other item: join with successors' usage"); @@ -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( @@ -424,8 +418,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // generic template parameters are used. let item_kind = ctx.resolve_item(item).as_type().map(|ty| ty.kind()); - if let Some(&TypeKind::TemplateInstantiation(ref inst)) = item_kind - { + if let Some(TypeKind::TemplateInstantiation(inst)) = item_kind { let decl = ctx.resolve_type(inst.template_definition()); let args = inst.template_arguments(); @@ -460,7 +453,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { } } - if cfg!(feature = "testing_only_extra_assertions") { + if cfg!(feature = "__testing_only_extra_assertions") { // Invariant: The `used` map has an entry for every allowlisted // item, as well as all explicitly blocklisted items that are // reachable from allowlisted items. @@ -471,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( @@ -481,7 +474,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { extra_assert!(dependencies.contains_key(&sub_item)); }, &(), - ) + ); } } @@ -499,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( @@ -519,14 +512,14 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // exiting this method. extra_assert!(self.used.values().all(|v| v.is_some())); - // Take the set for this id out of the hash map while we mutate it based + // Take the set for this ID out of the hash map while we mutate it based // on other hash map entries. We *must* put it back into the hash map at // the end of this method. This allows us to side-step HashMap's lack of // 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(); @@ -540,7 +533,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { } // Template instantiations only use their template arguments if the // template definition uses the corresponding template parameter. - Some(&TypeKind::TemplateInstantiation(ref inst)) => { + Some(TypeKind::TemplateInstantiation(inst)) => { if self .allowlisted_items .contains(&inst.template_definition().into()) @@ -563,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!( @@ -577,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 } } @@ -590,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 new file mode 100644 index 0000000000..7f5d74b3ee --- /dev/null +++ b/bindgen/ir/annotations.rs @@ -0,0 +1,259 @@ +//! Types and functions related to bindgen annotation comments. +//! +//! Users can add annotations in doc comments to types that they would like to +//! replace other types with, mark as opaque, etc. This module deals with all of +//! that stuff. + +use std::str::FromStr; + +use crate::clang; + +/// What kind of visibility modifier should be used for a struct or field? +#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default)] +pub enum FieldVisibilityKind { + /// Fields are marked as private, i.e., struct Foo {bar: bool} + Private, + /// Fields are marked as crate public, i.e., struct Foo {pub(crate) bar: bool} + PublicCrate, + /// Fields are marked as public, i.e., struct Foo {pub bar: bool} + #[default] + Public, +} + +impl FromStr for FieldVisibilityKind { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "private" => Ok(Self::Private), + "crate" => Ok(Self::PublicCrate), + "public" => Ok(Self::Public), + _ => Err(format!("Invalid visibility kind: `{s}`")), + } + } +} + +impl std::fmt::Display for FieldVisibilityKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + FieldVisibilityKind::Private => "private", + FieldVisibilityKind::PublicCrate => "crate", + FieldVisibilityKind::Public => "public", + }; + + s.fmt(f) + } +} + +/// What kind of accessor should we provide for a field? +#[derive(Copy, PartialEq, Eq, Clone, Debug)] +pub(crate) enum FieldAccessorKind { + /// No accessor. + None, + /// Plain accessor. + Regular, + /// Unsafe accessor. + Unsafe, + /// Immutable accessor. + Immutable, +} + +/// Annotations for a given item, or a field. +/// +/// You can see the kind of comments that are accepted in the [Doxygen documentation](https://www.doxygen.nl/manual/docblocks.html). +#[derive(Default, Clone, PartialEq, Eq, Debug)] +pub(crate) struct Annotations { + /// Whether this item is marked as opaque. Only applies to types. + opaque: bool, + /// Whether this item should be hidden from the output. Only applies to + /// types, or enum variants. + hide: bool, + /// Whether this type should be replaced by another. The name is a + /// namespace-aware path. + use_instead_of: Option>, + /// Manually disable deriving copy/clone on this type. Only applies to + /// struct or union types. + disallow_copy: bool, + /// Manually disable deriving debug on this type. + disallow_debug: bool, + /// Manually disable deriving/implement default on this type. + disallow_default: bool, + /// Whether to add a `#[must_use]` annotation to this type. + must_use_type: bool, + /// Visibility of struct fields. You can set this on + /// structs (it will apply to all the fields), or individual fields. + visibility_kind: Option, + /// The kind of accessor this field will have. Also can be applied to + /// structs so all the fields inside share it by default. + accessor_kind: Option, + /// Whether this enum variant should be constified. + /// + /// This is controlled by the `constant` attribute, this way: + /// + /// ```cpp + /// enum Foo { + /// Bar = 0, /**<